【问题标题】:How to create Selector with parameters from string如何使用字符串中的参数创建选择器
【发布时间】:2017-11-11 02:39:51
【问题描述】:

我正在使用 Swift 3.1 和 Xcode 8.3.3 编写程序。我想创建一个类,负责在键盘出现和消失时移动整个视图。但是我在使用字符串参数创建自定义选择器时遇到了困难。要显示或隐藏键盘,我们需要函数:

func keyboardWillShow(notification: Notification) {
//Code moving view when keyboard appears
}

我正在尝试创建这样的选择器:

let selector = Selector(("keyboardWillShow")
NotificationCenter.default.addObserver(view, selector: selector, name: .UIKeyboardWillShow, object: anyView.view.window)

它正在编译,但是当键盘出现时,它崩溃了。 因为它是独立类,所以我不能使用这种结构:

#selector(keyboardWillShow)

因为它将 Swift 函数转换为 Objective-C 函数(添加 @objc)。 那么问题来了:如何创建带参数字符串的 Selector 表单?

P。 S. 我可以把整个代码放在那里,但我不希望问题很大,所以如果有人问我会编辑问题...

【问题讨论】:

  • 不能用选择器传递参数,只能发送控制对象
  • 怎么做?你能举个例子吗?
  • 你已经这样做了...看看keyboardWillShow(notification: Notification)如果它有标签然后可以进入功能
  • 是的,但它正在崩溃。

标签: ios swift notifications selector observers


【解决方案1】:

这就是你想要的,带有字符串类型和通知参数参数的选择器

斯威夫特 4

NotificationCenter.default.addObserver(self, selector: Selector(("showKeyboard:")), name:NSNotification.Name.UIKeyboardWillShow, object: nil)

var keyboardHeight = 0.0
//-------------------
@objc func showKeyboard(_ sender: Notification) {
    keyboardWillShow(sender: sender as NSNotification, adjustHeight: 150)
    print("sender - \(sender)")
}

//-------------------
func keyboardWillShow(sender: NSNotification, adjustHeight: CGFloat) {
    if let keyboardSize = (sender.userInfo?[UIKeyboardFrameEndUserInfoKey] as? NSValue)?.cgRectValue {
        keyboardHeight = Double(keyboardSize.height)
        // do your calculations
    }
}


斯威夫特 3

NotificationCenter.default.addObserver(view, selector: Selector(("keyboardWillShow:")), name: .UIKeyboardWillShow, object: anyView.view.window)

func keyboardWillShow(_ notification: Notification) { 
       keyboardWillShow(sender: sender as NSNotification, adjustHeight: 150)
        print("sender - \(sender)")

} 



这是正常的选择器,根据语言支持
Swift 4

NotificationCenter.default.addObserver(self, selector: #selector(self.showKeyboard(sender:)), name:NSNotification.Name.UIKeyboardWillShow, object: nil)

var keyboardHeight = 0.0

    //-------------------
    @objc func showKeyboard(sender: NSNotification) {
        keyboardWillShow(sender: sender, adjustHeight: 150)
    }

    //-------------------
    func keyboardWillShow(sender: NSNotification, adjustHeight: CGFloat) {
        if let keyboardSize = (sender.userInfo?[UIKeyboardFrameEndUserInfoKey] as? NSValue)?.cgRectValue {
            keyboardHeight = Double(keyboardSize.height)
            // your operations here
        }
    }


斯威夫特 3

NotificationCenter.default.addObserver(self, selector: #selector(self.showKeyboard(sender:)), name:NSNotification.Name.UIKeyboardWillShow, object: nil)

var keyboardHeight = 0.0

    //-------------------
    func showKeyboard(sender: NSNotification) {
        keyboardWillShow(sender: sender, adjustHeight: 150)
    }

   //-------------------
    func keyboardWillShow(sender: NSNotification, adjustHeight: CGFloat) {
        if let keyboardSize = (sender.userInfo?[UIKeyboardFrameEndUserInfoKey] as? NSValue)?.cgRectValue {
            keyboardHeight = Double(keyboardSize.height)
            // your operations here
        }
    }

【讨论】:

  • 谢谢你的回答,但不太一样。问题是如何使用字符串中的参数创建选择器。此外,即使在 swift 3.1 中,您也不应该在没有特殊需要的情况下使用 NS 函数或变量。请下载我的项目,看看如何不使用 NSValue。
  • 请问,我可以再做一些 cmets 吗?
  • 首先,删除 @objc ,它会导致警告。第二:我认为我们不需要两个函数:showKeyboard 和keyboardWillShow。我们可以很容易地将它们合二为一。事实上,最有用的部分是: showKeyboard(_ sender: Notification) 这个符号“_”我正在寻找!谢谢!!!
  • 我不知道如何编辑其他答案,但没关系,它正在工作!其他人也会看到。再次非常感谢!!!
  • 请将您的代码粘贴到评论区。因为定性问题和答案是有用的,而不是简单的陈述。
【解决方案2】:

这种方法有效,

override func viewDidLoad() {
    super.viewDidLoad()
// put it wherever you want
 NSNotificationCenter.defaultCenter().addObserver(self, selector: #selector(showKeyboard), name:UIKeyboardWillShowNotification, object: nil)
}

func showKeyboard(sender: NSNotification) {
    keyboardWillShow(sender, adjustHeight: 150)
}

func keyboardWillShow(sender: NSNotification, adjustHeight: CGFloat) {
    if let keyboardSize = (sender.userInfo?[UIKeyboardFrameEndUserInfoKey] as? NSValue)?.CGRectValue() {
        keyboardHeight = keyboardSize.height
 // do your calculations
    }
}

这将帮助您实现预期的结果。

【讨论】:

  • 是的,这行得通,但主要是为了避免写这个 NSNotificationCenter.defaultCenter().addObserver(self, selector: #selector(keyboardWillShow), name:UIKeyboardWillShowNotification, object: nil) 和相同的 long在 ViewDidLoad 中隐藏键盘的行。
  • 这是一种通用方法,只要键盘出现或消失,就会调用选择器方法。那么你的期望是什么?!
  • 我要写一个类,普通类。所以,想法是避免长代码的重复。我可以对每个视图都采用你的方法,但我想避免这样做。
  • 您可以在基类中编写keyboardWillShow 并将其继承给其他类以访问该方法,但您必须在任何您需要的类中使用NSNotificationCenter
  • 现在看来只有一种方式...谢谢。但是,参数在选择器中仍然不可用?
猜你喜欢
  • 2017-07-22
  • 1970-01-01
  • 1970-01-01
  • 2010-09-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-01-21
  • 1970-01-01
相关资源
最近更新 更多