addTarget:action:forControlEvents: target 为 nil 时的选择器语法?

Posted

技术标签:

【中文标题】addTarget:action:forControlEvents: target 为 nil 时的选择器语法?【英文标题】:addTarget:action:forControlEvents: selector syntax when target is 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)

【问题讨论】:

【参考方案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)

【讨论】:

以上是关于addTarget:action:forControlEvents: target 为 nil 时的选择器语法?的主要内容,如果未能解决你的问题,请参考以下文章