4

I'm trying to implement UITextFieldDelegate in separate class, but it didn't working:

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

But this is working:

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

Is there something wrong?

JasonTW
  • 55
  • 8

1 Answers1

5

UITextField's .delegate is a weak property so at the end of viewDidLoad method, restrictor will be deallocated because there is no other strong reference around that is pointing to the object which it points to.

You can try printing out ValidationTextField.delegate in viewDidAppear(animated:) and see it returns nil.

To overcome this problem, you can define restrictor as an instance variable so it'll stay alive as long as the view controller is alive:

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

  let restrictor = TextFieldRestrictController()

  override func viewDidLoad() {
    super.viewDidLoad()
    ValidationTextField.delegate = restrictor
  }
}
Ozgur Vatansever
  • 49,246
  • 17
  • 84
  • 119