And*_*rea 25 protocols ios swift
我有一个协议扩展,它曾经在swift 2.2之前完美地工作.
现在我有一个警告,告诉我使用新的#selector
,但如果我添加它
没有使用Objective-C Selector声明的方法.
我尝试在这几行代码中重现这个问题,可以很容易地复制并粘贴到游乐场
protocol Tappable {
func addTapGestureRecognizer()
func tapGestureDetected(gesture:UITapGestureRecognizer)
}
extension Tappable where Self: UIView {
func addTapGestureRecognizer() {
let gesture = UITapGestureRecognizer(target: self, action:#selector(Tappable.tapGestureDetected(_:)))
addGestureRecognizer(gesture)
}
}
class TapView: UIView, Tappable {
func tapGestureDetected(gesture:UITapGestureRecognizer) {
print("Tapped")
}
}
Run Code Online (Sandbox Code Playgroud)
还有一个建议在协议中附加到该方法@objc
,但是如果我这样做也要求我将它添加到实现它的类中,但是一旦我添加该类就不再符合协议,因为它不会好像在协议扩展中看到了实现.
我该如何正确实现?
小智 24
我遇到了类似的问题.这就是我做的.
然后使用Self.在#selector中.
@objc public protocol UpdatableUserInterfaceType {
optional func startUpdateUITimer()
optional var updateInterval: NSTimeInterval { get }
func updateUI(notif: NSTimer)
}
public extension UpdatableUserInterfaceType where Self: ViewController {
var updateUITimer: NSTimer {
return NSTimer.scheduledTimerWithTimeInterval(updateInterval, target: self, selector: #selector(Self.updateUI(_:)), userInfo: nil, repeats: true)
}
func startUpdateUITimer() {
print(updateUITimer)
}
var updateInterval: NSTimeInterval {
return 60.0
}
}
Run Code Online (Sandbox Code Playgroud)小智 17
您可以创建一个属性作为选择器...示例:
protocol Tappable {
var selector: Selector { get }
func addTapGestureRecognizer()
}
extension Tappable where Self: UIView {
func addTapGestureRecognizer() {
let gesture = UITapGestureRecognizer(target: self, action: selector)
addGestureRecognizer(gesture)
}
}
class TapView: UIView, Tappable {
var selector = #selector(TapView.tapGestureDetected(_:))
func tapGestureDetected(gesture:UITapGestureRecognizer) {
print("Tapped")
}
}
Run Code Online (Sandbox Code Playgroud)
错误停止显示,并且不再需要使用@objc装饰器设置协议和类.
这个解决方案不是最优雅的,但直到现在看起来还不错.
这个答案与Bruno Hecktheuers非常相似,但是我们选择将它作为参数传递给addTapGestureRecognizer函数,而不是让每个想要符合"Tappable"协议的人实现变量"selector".
protocol Tappable {
func addTapGestureRecognizer(selector selector: Selector)
func tapGestureDetected(gesture:UITapGestureRecognizer)
}
extension Tappable where Self: UIView {
func addTapGestureRecognizer(selector selector: Selector)
let gesture = UITapGestureRecognizer(target: self, action: selector)
addGestureRecognizer(gesture)
}
}
class TapView: UIView, Tappable {
func tapGestureDetected(gesture:UITapGestureRecognizer) {
print("Tapped")
}
}
Run Code Online (Sandbox Code Playgroud)
然后只需将选择器传递到任何地方:
addTapGestureRecognizer(selector: #selector(self.tapGestureDetected(_:)))
Run Code Online (Sandbox Code Playgroud)
这样我们就可以避免让实现此协议的人必须实现选择器变量,并且我们也避免使用"@objc"标记每个人使用此协议.像这种方法的感觉不那么臃肿.
归档时间: |
|
查看次数: |
8892 次 |
最近记录: |