从 didSet 调用方法时委托 returns nil

Delegate returns nil when calling method from a didSet

我有一个 UITextField 的子类,用于在特定的 textField 事件之后调用两个方法。 textField 使用 delegate/protocol 设置调用 textField 超类中的方法。

class SearchTermCellTextField: UITextField {

    var searchTermCellTextFieldDelegate: SearchTermCellTextFieldDelegate?

    override var text: String? {
        didSet {
            searchTermCellTextFieldDelegate?.textFieldDidChange(self)
        }
    }

    override func deleteBackward() {
        super.deleteBackward()
        searchTermCellTextFieldDelegate?.textFieldReceivedDelete(self)
    }

}

protocol SearchTermCellTextFieldDelegate {

    func textFieldReceivedDelete(_ textField: UITextField)

    func textFieldDidChange(_ textField: UITextField)

}

代理初始化正确,textFieldReceivedDelete()调用没有问题。但是,每次调用 textFieldDidChange() 时(在 var text { didSet } 中),searchTermCellTextFieldDelegate 的值为 nil。

我尝试将searchTermCellTextFieldDelegate?.textFieldDidChange()放入didSet调用的辅助方法中,看看它是否有任何效果,但仍然是一样的。我在 deleteBackward() 中测试了它——我不想要它的地方——并且 searchTermCellTextFieldDelegate? 具有预期的非零值并且它可以正常触发。

我唯一的猜测是文本变量 { get set } 中发生了一些更复杂的事情导致了这个问题,但除此之外我不知道从哪里开始解决问题。

有没有人有任何见解?提前致谢。

原因 - 您确实覆盖了 A textField 的文本,但 OP 想要触发的功能 textFieldDidChange 是基于编辑更改的控制事件,因此在您的情况下不需要覆盖 text 作为文本更改或编辑其值时不会触发

因此,要使 class 委托工作,您实际上需要关注编辑 TextField 的更改控制事件

试试这个

import Foundation
import UIKit


class SearchTermCellTextField: UITextField {

    var TFDelegate : SearchTermCellTextFieldDelegate?

    /// Initialise class
    override init(frame: CGRect) {
        super.init(frame: frame)
        /// Need to add a target to notify class that text did changed
        self.addTarget(self, action: #selector(SearchTermCellTextField.editingChanged), for: .editingChanged)
    }

    /// Coder
    required init?(coder aDecoder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }

    /// You override Text Not its editing changed
    override var text: String? {
        didSet {
            TFDelegate?.textFieldDidChange(self)
        }
    }

    /// Handler which tells that editing has been changed
    @objc func editingChanged(){
        TFDelegate?.textFieldDidChange(self)
    }

    /// Its Working
    override func deleteBackward() {
        super.deleteBackward()
        TFDelegate?.textFieldReceivedDelete(self)
    }

}

protocol SearchTermCellTextFieldDelegate {

    func textFieldReceivedDelete(_ textField: UITextField)

    func textFieldDidChange(_ textField: UITextField)

}

ViewController class

import UIKit

class ViewController: UIViewController {
    private var myFirstTF : SearchTermCellTextField?
}

/// View Life cycles
extension ViewController
{
    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view, typically from a nib.
        myFirstTF = SearchTermCellTextField()
        myFirstTF?.TFDelegate = self
        myFirstTF?.placeholder = "Enter Text"

        myFirstTF?.translatesAutoresizingMaskIntoConstraints = false
        self.view.addSubview(myFirstTF!)
        myFirstTF?.leadingAnchor.constraint(equalTo: self.view.leadingAnchor, constant: 20).isActive=true
        myFirstTF?.trailingAnchor.constraint(equalTo: self.view.trailingAnchor, constant: 20).isActive=true
        myFirstTF?.topAnchor.constraint(equalTo: self.view.topAnchor, constant: 100).isActive=true
        myFirstTF?.heightAnchor.constraint(equalToConstant: 50)

    }
}

extension ViewController: SearchTermCellTextFieldDelegate
{    
    func textFieldReceivedDelete(_ textField: UITextField) {
        print("delete Recieved")
    }

    func textFieldDidChange(_ textField: UITextField) {
        print("Text:\(textField.text ?? "Empty")")
    }
}

控制台输出