UITextFieldDelegate扩展函数没有触发,为什么?

时间:2017-10-30 15:49:29

标签: swift uitextfield protocols

我有SequencedTextFields协议,其中包含一系列文本字段。当用户点击键盘上的Return按钮时,当前文本字段应该退出第一响应者,序列中的下一个文本字段应该成为第一响应者。当我使用UITextFieldDelegate协议直接实现视图控制器时,它运行良好:

extension MyViewController: UITextFieldDelegate {
    func textFieldShouldReturn(_ textField: UITextField) -> Bool {
        textField.resignFirstResponder()
        nextInSequence(after: textField)?.becomeFirstResponder()
        return true
    }
}

但是,当我尝试使用default实施时,它不会触发:

extension UITextFieldDelegate where Self: SequencedTextFields {
    func textFieldShouldReturn(_ textField: UITextField) -> Bool {
        textField.resignFirstResponder()
        nextInSequence(after: textField)?.becomeFirstResponder()
        return true
    }
}

可能是什么原因?或者我错过了什么?

更新:

我的视图控制器定义:

final class MyViewController: UIViewController, UITextFieldDelegate, SequencedTextFields

设置文本字段的委托: enter image description here

2 个答案:

答案 0 :(得分:1)

您的实现无效的原因是您尝试扩展接口(UITextFieldDelegate)而不是类,这就是为什么当您使用UIViewController时它的工作原理。

您可以做的是创建扩展SequencedTextField的自定义类 UITextField。添加一个自定义委托(我称之为sequencedDelegate代表实现SequencedTextFields协议的类。

扩展 SequencedTextField以使用您的默认实施方式实施UITextFieldDelegate

MyViewController上,使用SequencedTextField本身设置viewController代表。

最后看起来应该是这样的:

protocol SequencedTextFields: class {
    func nextInSequence(after: UITextField) -> UITextField?
}

class SequencedTextField: UITextField {
    weak var sequencedDelegate: SequencedTextFields?
}

extension SequencedTextField: UITextFieldDelegate {
    public func textFieldShouldReturn(_ textField: UITextField) -> Bool {
        textField.resignFirstResponder()
        sequencedDelegate?.nextInSequence(after: textField)?.becomeFirstResponder()
        return true
    }
}

class MyViewController : UIViewController, SequencedTextFields {
    var textField = SequencedTextField()

    override func viewDidLoad() {
        super.viewDidLoad()
        textField.delegate = textField
        textField.sequencedDelegate = self
    }

    func nextInSequence(after: UITextField) -> UITextField? {
        // your view controllers nextInSequence implementation here
    }
}

答案 1 :(得分:0)

您的代码有什么问题?

第一个扩展名是视图控制器MyViewController的扩展名,这就是它工作的原因。但第二个是UITextFieldDelegate的扩展。这些完全是两件事。

不清楚你想要达到的目标。

您可以使用自定义协议

如果你想为你的特殊UITextField制作一个CustomProtocol,你可以这样做。

<强> CustomTextFieldProtocol

  • 明确协议

    protocol SequencedTextFields: UITextFieldDelegate {
        func checkSomeThing(_ textField: UITextField) -> Bool
    }
    
  • 设置代理

    self.textField.delegate = self
    
  • ViewController Extension实现您的Delegate方法

    extension ViewController: SequencedTextFields {
    
        func textFieldShouldReturn(_ textField: UITextField) -> Bool {
            textField.resignFirstResponder()
            nextInSequence(after: textField)?.becomeFirstResponder()
            return true
        }
    
        func checkSomeThing(_ textField: UITextField) -> Bool {
            print("Check here")
            return true
        }
    }