【问题标题】:addTarget:action:forControlEvents: selector syntax when target is nil?addTarget:action:forControlEvents: target 为 nil 时的选择器语法?
【发布时间】:2017-07-21 17:06:32
【问题描述】:

我希望父 ViewController 处理其子 ViewControllers 生成的 Target-Action。

根据 Apple 文档,这应该可以通过将 target 设置为 nil 并遵循响应者链来实现。

如果您为目标对象指定 nil,则控件将搜索 定义指定动作的对象的响应者链 方法。 https://developer.apple.com/documentation/uikit/uicontrol

但是当targetnil 时,我该如何写动作方法签名呢?

通常您将函数名称包含在#selector() 中,这使您可以在编译时检查具有该签名的方法是否存在。像这样:

class MyViewController: UIViewController {
    override func viewDidLoad() {
         self.button.addTarget(self, action: #selector(buttonPressed(sender:)), for: .touchDown)
    }

    func buttonPressed(sender: UIButton) { }

}

但由于targetnil,编译器会抱怨因为找不到它:

// ! Use of unresolved identifier "buttonPressed(sender:)"
button.addTarget(nil, action: #selector(buttonPressed(sender:)), for: .touchDown)

我尝试使用字符串初始化选择器,但编译器也报错。

    // ! String literal is not a valid Objective-C selector
    button.addTarget(nil, action: Selector("buttonPressed(sender:)"), for: .touchDown)

【问题讨论】:

    标签: swift uicontrol responder-chain


    【解决方案1】:

    解决方案是在定义类的名称前面加上前缀。

        button.addTarget(nil, action: #selector(MyViewController.buttonPressed(sender:)), for: .touchDown)
    

    仅供参考,我通过this nice blog post from Jan 2016 得到了答案,下载了源文件,并让 XCode 将其转换为 Swift 3 语法 :-)

    【讨论】:

    • 但这肯定违背了这一点:响应者可以在没有明确预定义响应者的情况下响应选择器..
    • 你是什么意思?因为现在选择器必须是MyViewController中定义的方法?我希望我的孩子的操作由其父母处理,所以我希望我的选择器在父母中定义。
    • 响应者链机制的思想是,响应者是可能的响应者链中的第一个,而无需明确指定哪个响应者将响应,从而允许松散耦合..
    【解决方案2】:

    这对我有用,请注意双括号以避免警告: NSApp.sendAction(Selector(("enterActivationNumber:")), to: nil, from: sender)

    【讨论】:

      猜你喜欢
      • 2011-10-15
      • 1970-01-01
      • 2019-07-19
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多