我希望有一个视图函数,它返回与给定类型匹配的第一个UIResponder:
extension UIView {
func responder<T, Result: UIResponder & T>(ofType: T) -> Result? {
var parentResponder: UIResponder? = self
while parentResponder != nil {
parentResponder = parentResponder?.next
if let matchingResponder = parentResponder as? Result {
return matchingResponder
}
}
return nil
}
}
不幸的是,编译器显示以下错误:
Non-protocol, non-class type 'T' cannot be used within a protocol-constrained type
我的问题很简单:如何告诉编译器T是协议类型?
答案 0 :(得分:2)
你不需要两个论点,一个就足够了。您还可以为type
参数提供默认值,以防编译器推断结果:
extension UIView {
func findResponder<T>(ofType type: T.Type = T.self) -> T? {
func find(_ current: UIResponder) -> T? {
if let result = current as? T { return result }
guard let next = current.next else { return nil }
return find(next)
}
return find(self)
}
}
请注意,您不能将T
限制为仅作为协议,因为在Swift协议中不是第一类类型。但是你不应该这样做。
我还将方法实现重新组织为更具功能性的风格。
用法:
let dataSource = view.findResponder(ofType: UITableViewDataSource.self)
let navCtrl: UINavigationController = view.findResponder()