ios – 类扩展崩溃中的Swift NSNotificationCenter观察者

ios – 类扩展崩溃中的Swift NSNotificationCenter观察者,第1张

概述我试图创建一个通用机制,可以对iOS中的键盘显示和隐藏作出反应.我提出了简单的协议及其扩展,它不包含真实的动画,但是从采用这个协议的对象中提取它们: import UIKitprotocol KeyboardAnimatable { func keyboardWillShowAnimation() -> (() -> Void)? func keyboardWillHideAn 我试图创建一个通用机制,可以对iOS中的键盘显示和隐藏作出反应.我提出了简单的协议及其扩展,它不包含真实的动画,但是从采用这个协议的对象中提取它们:

import UIKitprotocol KeyboardAnimatable {    func keyboarDWillShowAnimation() -> (() -> VoID)?    func keyboarDWillHIDeAnimation() -> (() -> VoID)?}extension KeyboardAnimatable where Self: UIVIEwController {    func setupKeyboardNotifcationListeners() {        NSNotificationCenter.defaultCenter().addobserver(self,selector: Selector("keyboarDWillShow:"),name: UIKeyboarDWillShowNotification,object: nil)        NSNotificationCenter.defaultCenter().addobserver(self,selector: Selector("keyboarDWillHIDe:"),name: UIKeyboarDWillHIDeNotification,object: nil)    }    func removeKeyboardNotificationListeners() {        NSNotificationCenter.defaultCenter().removeObserver(self,object: nil)        NSNotificationCenter.defaultCenter().removeObserver(self,object: nil)    }    func keyboarDWillShow(notification: NSNotification) {        let userInfo = notification.userInfo as! Dictionary<String,AnyObject>        let animationDuration = userInfo[UIKeyboardAnimationDurationUserInfoKey] as! NSTimeInterval        let animationCurve = userInfo[UIKeyboardAnimationCurveUserInfoKey]!.intValue        let curveAnimationoption = UIVIEwAnimationoptions(rawValue: UInt(animationCurve))        let options: UIVIEwAnimationoptions = [.BeginFromCurrentState,curveAnimationoption]        if let animation = keyboarDWillShowAnimation() {            UIVIEw.animateWithDuration(animationDuration,delay: 0,options: options,animations: animation,completion: nil)        }    }    func keyboarDWillHIDe(notification: NSNotification) {        let userInfo = notification.userInfo as! Dictionary<String,curveAnimationoption]        if let animation = keyboarDWillHIDeAnimation() {            UIVIEw.animateWithDuration(animationDuration,completion: nil)        }    }}

我在扩展KeyboardAnimatable中明确使用where子句,其中Self:UIVIEwController将其缩小,以便在添加观察者时可以使用self.
现在我可以创建一个采用这种协议的视图控制器,例如键盘显示时更改约束:

import UIKitclass VIEwController: UIVIEwController,KeyboardAnimatable {    @IBOutlet weak var constraintYCenter: NSLayoutConstraint!    overrIDe func vIEwDIDLoad() {        super.vIEwDIDLoad()        setupKeyboardNotifcationListeners()    }    func keyboarDWillShowAnimation() -> (() -> VoID)? {        return {            self.constraintYCenter.constant = 100            self.vIEw.layoutIfNeeded()        }    }    func keyboarDWillHIDeAnimation() -> (() -> VoID)? {        return nil    }//    func keyboarDWillShow(notification: NSNotification) {//        print("will show")//    }//    //    func keyboarDWillHIDe(notification: NSNotification) {//        print("will hIDe")//    }    deinit {        removeKeyboardNotificationListeners()    }}

但是,当我运行此代码时,应用程序崩溃并出现以下错误:

*** Terminating app due to uncaught exception 'NSinvalidargumentexception',reason: '-[KeyboardAnimatableDemo.VIEwController keyboarDWillShow:]: unrecognized selector sent to instance 0x7fb429f192d0'

看起来我的视图控制器不使用在协议扩展中实现的keyboarDWillShow:方法.
当我取消注释直接在VIEwController中实现的这两个方法时,它们可以工作(打印日志),但是使用普通键盘动画制作工具的整个概念是无用的.

我认为在setupKeyboardNotifcationListeners()中可能会发生一些奇怪的事情,但即使我将其更改为例如func setupKeyboardNotifcationListeners(vc:UIVIEwController)并且在注册观察者时没有任何更改时使用vc而不是self.

一种可能的解决方案也可以是仅为采用该协议的控制器的子集创建UIVIEwController扩展.类似于这个扩展UIVIEwcontroller的地方Self:KeyboardAnimatable但是这个没有编译,我没有找到任何这样的定义的例子,所以它甚至可能在Swift中不可能.

有没有人试图实现类似的东西,他成功了?

解决方法 我通过删除协议并为这些方法引入“空”实现来解决这个问题.现在,键盘的扩展直接扩展了UIVIEwController,所以它应该很容易使用.

代码依旧:https://gist.github.com/AdamSliwakowski/6fa1e920254ce584d203

总结

以上是内存溢出为你收集整理的ios – 类扩展崩溃中的Swift NSNotificationCenter观察者全部内容,希望文章能够帮你解决ios – 类扩展崩溃中的Swift NSNotificationCenter观察者所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址: https://outofmemory.cn/web/1028467.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-05-23
下一篇 2022-05-23

发表评论

登录后才能评论

评论列表(0条)

保存