swift 2.0 - UITextFieldDelegate protocol extension not working
我正在尝试使用协议扩展在某些
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | extension ViewController: UITextFieldDelegate { // Works if I uncommented this so I know delegates are properly set // func textFieldShouldReturn(textField: UITextField) -> Bool { // textField.resignFirstResponder() // return true // } } extension UITextFieldDelegate { func textFieldShouldReturn(textField: UITextField) -> Bool { textField.resignFirstResponder() return true } } |
您可能会猜到,键盘永远不会消失。 我真的看不到这里出了什么问题。 这是语言限制吗? 有人已经成功做到了吗?
编辑:
如@Logan所建议,默认协议的方法实现不适用于标记为
我已经测试了
1 2 3 4 5 6 7 8 9 10 11 12 13 | protocol Toto: NSObjectProtocol { func randomInt() -> Int } extension Toto { func randomInt() -> Int { return 0 } } class Tata: NSObject, Toto {} let int = Tata().randomInt() // returns 0 |
我不能100%积极,但是我相信这是正在发生的事情:
无法从
为了明确起见,我们可以扩展这些协议(如果它确实是扩展名)并增加行为。此行为只能在Swift中访问,并且绝不会出现任何问题。
问题是默认实现无法访问
这是自定义版本的快速示例:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | @objc protocol Test : class { func someFunc() -> String } extension Test { func someFunc() -> String { return"" } } // Fails here 'candidate is not @objc but protocol requires it` class Hi : NSObject, Test { } |
Xcode建议附加
根据下面的对话,我认为这似乎可行。我还不能完全解释原因:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | @objc public protocol Toto: UITextFieldDelegate { optional func randomInt() -> Int } extension Toto { func randomInt() -> Int { return 0 } func textFieldShouldReturn(textField: UITextField) -> Bool { return false } } class Tata: NSObject, Toto { } |
好的,我意识到我正在考虑一个不同的问题,尽管此问题可以编译,但无法正常工作,而该问题是动态调度。如果您尝试使用w /
由于Swift会不断更新,因此适用此答案的时间是:
Swift 2.0 Xcode 7 GM
这里很好的讨论,以及我在这一点上的怀疑。
此处未提及的另一件事-可能是由于obj-c无法访问Swift协议扩展实现的更广泛的问题。
例如,以下代码:
1 2 3 4 5 6 7 8 9 10 11 12 | class MyViewController: UIViewController, MyTextFieldDelegateProtocol { @IBOutlet weak var textField: UITextField! override func viewDidLoad() { super.viewDidLoad() textField.delegate = self } } extension MyViewController: UITextFieldDelegate { func textFieldDidBeginEditing(textField: UITextField) { print("shouldChangeCharactersInRange called") } } |
将在Swift生成的扩展头中生成以下内容:
1 2 3 | @interface MyViewController (SWIFT_EXTENSION(MyApp)) <UITextFieldDelegate> - (void)textFieldDidBeginEditing:(UITextField * __nonnull)textField; @end |
但是,使用以下协议扩展(类似于您的帖子):
1 2 3 4 5 6 7 8 9 10 | class MyViewController: UIViewController, MyTextFieldDelegateProtocol { // ... } @objc protocol MyTextFieldDelegateProtocol: UITextFieldDelegate {} extension MyTextFieldDelegateProtocol { func textFieldDidBeginEditing(textField: UITextField) { print("shouldChangeCharactersInRange called") } } |
在Swift头中为协议生成以下内容:
1 2 3 | SWIFT_PROTOCOL("_TtP8MyApp27MyTextFieldDelegateProtocol_") @protocol MyTextFieldDelegateProtocol <UITextFieldDelegate> @end |
该实现完全不可见,因此似乎暗示obj-c不支持协议扩展实现。我还发现有人在这里问了这个问题(尽管还没有答案):
是否可以在Objective-c中访问的协议扩展上定义Swift方法
不幸的是,我尚未找到有关此限制的任何官方Apple文档。