如何使用另一个类的选择器?

ilo*_*acs 5 selector swift swift3 ios10

我有一个名为 FooFramework 的 Cocoa Touch 框架。

在其中,我想在键盘显示时管理所选视图在 Y 轴上的向上移动。我创建了一个KeyboardManager类。它看起来是这样的:

import UIKit

public class KeyboardManager {
    var notifyFromObject: Any?
    var observer: Any
    public var viewsToPushUp: [UIView] = []

    public init(observer: Any, viewsToPushUp: [UIView], notifyFromObject: Any? = nil) {
        self.observer = observer
        self.notifyFromObject = notifyFromObject
        self.viewsToPushUp = viewsToPushUp
    }

    public func pushViewsUpWhenKeyboardWillShow(){
        let notificationCenter = NotificationCenter.default
        print(self)
        notificationCenter.addObserver(self.observer, selector: #selector(FooFramework.KeyboardManager.pushViewsUp), name: NSNotification.Name.UIKeyboardWillShow, object: notifyFromObject)
    }

    @objc public func pushViewsUp(notification: NSNotification) {
        if let keyboardRectValue = (notification.userInfo?[UIKeyboardFrameEndUserInfoKey] as? NSValue)?.cgRectValue {
            let keyboardHeight = keyboardRectValue.height

            for view in viewsToPushUp {
                view.frame.origin.y -= keyboardHeight
            }
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

然后,我将此 FooFramework 导入到名为 Bar 的 iOS 应用程序中。为了测试 FooFramework,我想推送一个UITextField. 这是代码:

import UIKit
import FooFramework

class ViewController: UIViewController {

    @IBOutlet weak var textField: UITextField!

    override func viewWillAppear(_ animated: Bool) {
        super.viewWillAppear(animated)
        let kb = KeyboardManager(observer: self, viewsToPushUp: [textField], notifyFromObject: nil)
        kb.pushViewsUpWhenKeyboardWillShow()
    }

    func pushViewsUp(notification: NSNotification) {
        print("This should not be printed")
    }
}
Run Code Online (Sandbox Code Playgroud)

我的问题是This should not be printed出现在控制台中并且永远不会调用该pushViewsUp方法。KeyboardManager尽管我为选择器使用了完全限定名称,但它仍然坚持使用pushViewsUpViewController 中的 。这让我抓狂。

pushViewsUp如果我从 ViewController 中删除,则会收到以下错误:

Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[Bar.ViewController pushViewsUpWithNotification:]: unrecognized selector sent to instance 0x7fc540702d80'

我需要做什么才能使选择器正确指向FooFramework.KeyboardManager.pushViewsUp

小智 4

我相信您需要在函数中使用self而不是self.observer用于观察者addObserver

此外,您还需要kb在函数范围之外声明变量,以便管理器检测到通知。

例子:

import UIKit
import FooFramework

class ViewController: UIViewController {

    @IBOutlet weak var textField: UITextField!

    var kb: KeyboardManager?

    override func viewWillAppear(_ animated: Bool) {
        super.viewWillAppear(animated)
        kb = KeyboardManager(observer: self, viewsToPushUp: [textField], notifyFromObject: nil)
        kb?.pushViewsUpWhenKeyboardWillShow()
    }
}
Run Code Online (Sandbox Code Playgroud)

KeyboardManager变化:

public func pushViewsUpWhenKeyboardWillShow() {
    let notificationCenter = NotificationCenter.default
    print(self)
    notificationCenter.addObserver(self, 
                                   selector: #selector(FooFramework.KeyboardManager.pushViewsUp), 
                                   name: NSNotification.Name.UIKeyboardWillShow, 
                                   object: notifyFromObject)
}
Run Code Online (Sandbox Code Playgroud)