swift - UITextFieldDelegate 扩展函数不触发,为什么?

标签 swift uitextfield protocols

我有 SequencedTextFields 协议(protocol),它包含文本字段序列。当用户点击键盘上的 Return 按钮时,当前文本字段应退出第一响应者,序列中的下一个文本字段应成为第一响应者。当我为 View Controller 使用 UITextFieldDelegate 协议(protocol)的直接实现时,效果很好:

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
    }
}

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

更新:

我的 View Controller 定义:

final class MyViewController: UIViewController, UITextFieldDelegate, SequencedTextFields

为文本字段设置委托(delegate): enter image description here

最佳答案

你的实现不起作用的原因是因为你试图扩展一个接口(interface)(UITextFieldDelegate)而不是一个类,这就是为什么它在你使用 UIViewController 时起作用反而。

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

扩展 SequencedTextField 以使用默认实现实现 UITextFieldDelegate

MyViewController 上,使用 viewController 本身设置您的 SequencedTextField 委托(delegate)。

最后应该是这样的:

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
    }
}

关于swift - UITextFieldDelegate 扩展函数不触发,为什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47019304/

相关文章:

ios - 如何在 Xcode 中为大量现有的 swift 文件和类添加前缀

ios - 跟踪所有运行 block

swift - 在 Xcode 6.0 模式中创建环境变量并从 swift 中的代码中获取它们

ios - UIPickerView 为空

ios - Swift 在协议(protocol)中声明类函数

ios - 面向协议(protocol)编程和 Swift 类

swift - 定义一个将 Collection 作为属性的协议(protocol)

iOS 11 无法禁用复制粘贴选项 UITextField

ios - 使文本字段背景透明,但占位符文本不透明

swift - Swift 协议(protocol)中的弱属性只能是类或类绑定(bind)协议(protocol)类型