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
但是当target
是nil
时,我该如何写动作方法签名呢?
通常您将函数名称包含在#selector()
中,这使您可以在编译时检查具有该签名的方法是否存在。像这样:
class MyViewController: UIViewController
override func viewDidLoad()
self.button.addTarget(self, action: #selector(buttonPressed(sender:)), for: .touchDown)
func buttonPressed(sender: UIButton)
但由于target
是nil
,编译器会抱怨因为找不到它:
// ! 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 时的选择器语法?的主要内容,如果未能解决你的问题,请参考以下文章