如何在 Swift 中单独设置 UITextField 的委托 class?

How to set delegate of UITextField in separate class in Swift?

我正在尝试在单独的 class 中实施 UITextFieldDelegate,但没有成功:

class ViewController: UIViewController {

    @IBOutlet var TextField: UITextField!

    override func viewDidLoad() {
        super.viewDidLoad()
        let restrictor = TextFieldRestrictController()
        TextField.delegate = restrictor
    }
}

class TextFieldRestrictController : NSObject, UITextFieldDelegate {

    public func textField(_ textField: UITextField,
                          shouldChangeCharactersIn range: NSRange,
                          replacementString string: String) -> Bool {
        let inverseSet = NSCharacterSet(
            charactersIn:"0123456789.").inverted

        let components = string.components(separatedBy: inverseSet)

        let filtered = components.joined(separator:"")
        return string == filtered
    }
}

但这是有效的:

class ViewController: UIViewController {

    @IBOutlet var TextField: UITextField!

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

    public func textField(_ textField: UITextField,
                          shouldChangeCharactersIn range: NSRange,
                          replacementString string: String) -> Bool {
        let inverseSet = NSCharacterSet(
            charactersIn:"0123456789.").inverted

        let components = string.components(separatedBy: inverseSet)

        let filtered = components.joined(separator:"")
        return string == filtered
    }
}

有什么问题吗?

UITextField.delegate 是一个 weak 属性 所以在 viewDidLoad 方法的最后, restrictor 将被释放,因为周围没有其他强引用指向它指向的对象。

您可以尝试在 viewDidAppear(animated:) 中打印出 ValidationTextField.delegate 并查看 returns nil.

为了克服这个问题,您可以将 restrictor 定义为实例变量,这样只要视图控制器处于活动状态,它就会保持活动状态:

class ViewController: UIViewController {
  @IBOutlet weak var ValidationTextField: UITextField!

  let restrictor = TextFieldRestrictController()

  override func viewDidLoad() {
    super.viewDidLoad()
    ValidationTextField.delegate = restrictor
  }
}