我有我认为是一个非常简单的协议扩展,我UIViewController提供了通过轻击手势解雇键盘的功能.这是我的代码:
@objc protocol KeyboardDismissing {
func on(tap: UITapGestureRecognizer)
}
extension KeyboardDismissing where Self: UIViewController {
func addDismissalGesture() {
let tap = UITapGestureRecognizer(target: self, action: #selector(Self.on(tap:)))
view.addGestureRecognizer(tap)
}
func on(tap: UITapGestureRecognizer) {
dismissKeyboard()
}
func dismissKeyboard() {
view.endEditing(true)
}
}
Run Code Online (Sandbox Code Playgroud)
问题是上面的代码在这一行引发编译错误:
let tap = UITapGestureRecognizer(target: self, action: #selector(Self.on(tap:)))
Run Code Online (Sandbox Code Playgroud)
带有错误消息:
'#selector'的参数是指没有暴露给Objective-C的实例方法'on(tap :)'
建议通过@objc之前添加"修复它"func on(tap: UITapGestureRecognizer)
好的,我添加标签:
@objc func on(tap: UITapGestureRecognizer) {
dismissKeyboard()
}
Run Code Online (Sandbox Code Playgroud)
但是,它会在这个新添加的@objc标记上抛出一个不同的编译错误,并显示错误消息:
@objc只能用于类的成员,@ objc协议和类的具体扩展
通过删除我刚刚被告知添加的完全相同的标签来建议"修复它" .
我原先认为@objc在我的协议定义之前添加可以解决任何#selector问题,但显然情况并非如此,这些周期性错误消息/建议没有丝毫帮助.我已经 …
我建立简单的主题引擎,并希望有一个扩展,它增加了UISwipeGestureRecognizer对UIViewController
这是我的代码:
protocol Themeable {
func themeDidUpdate(currentTheme: Theme) -> Void
}
extension Themeable where Self: UIViewController {
func switchCurrentTheme() {
Theme.switchTheme()
themeDidUpdate(Theme.currentTheme)
}
func addSwitchThemeGestureRecognizer() {
let gestureRecognizer = UISwipeGestureRecognizer(target: self, action:#selector(Self.switchCurrentTheme))
gestureRecognizer.direction = .Down
gestureRecognizer.numberOfTouchesRequired = 2
self.view.addGestureRecognizer(gestureRecognizer)
}
}
Run Code Online (Sandbox Code Playgroud)
当然编译器找不到,#selector(Self.switchCurrentTheme)因为它没有通过@objc指令公开.是否可以将此行为添加到我的扩展程序?
UPDATE: Theme是一个Swift枚举,所以我不能@objc在Themeable协议前添加
我有一个协议,充当一个视图和另一个视图之间的委托.
协议看起来像这样:
protocol MyProtocol: class {
func functionOne()
}
Run Code Online (Sandbox Code Playgroud)
协议的实现方式View2如下:
extension View2:MyProtocol {
func functionOne() {
print("Hello World"
}
}
Run Code Online (Sandbox Code Playgroud)
现在我希望这个方法被一个按钮的目标调用View1.所以在View1我有一条线:
myButton(self, action: #selector(delegate?.functionOne), forControlEvents: .TouchUpInside)
Run Code Online (Sandbox Code Playgroud)
但是按钮行错误"Use of unresolved identifier 'functionOne'",这是我以前在其他问题中没有见过的错误.
如果我functionTwo进入View1并设置目标functionTwo,然后functionTwo通过直接调用实现,一切都有效delegate?.functionOne.但这似乎非常不优雅.