Search code examples
iosswiftuitextfieldnsnotification

UITextField subclass - subscribing to events


I've created a subclass of UITextField which has its own visual style and functionality. The functionality is to restrict the user to decimal currency values (for example, 3.50), but that's not really relevant because I know the algorithm I have works. The issue is that I want to contain that logic in the text field subclass itself. So far I've succeeded in capturing the delegate equivalents of textFieldDidBeginEditing and textFieldDidEndEditing:

NSNotificationCenter.defaultCenter().addObserver(self, selector: "didBeginEditing", name: UITextFieldTextDidBeginEditingNotification, object: self)
NSNotificationCenter.defaultCenter().addObserver(self, selector: "didEndEditing", name: UITextFieldTextDidEndEditingNotification, object: self)

Working well. Now I need a way to check if the user is entering valid input and update its text only if that character is valid (like shouldChangeCharactersInRange, but without a delegate), but I need to do this from within that text field subclass itself. Otherwise, I'm just repasting 40 lines of code in every view controller that has this type of field.


Solution

  • So far I've succeeded in capturing the delegate equivalents of textFieldDidBeginEditing and textFieldDidEndEditing

    But you've gone about this wrong way. Don't use notifications; there is no need.

    Simply have the UITextField subclass make self the delegate of self!

    self.delegate = self
    

    Now all the UITextFieldDelegate methods will arrive to the UITextField subclass itself. Implement any of those methods that interest you, right there in the subclass, and you're done.

    That approach, however, has one drawback: you've "stolen" the text field's delegate and cannot easily make some other object the delegate. So here's another approach: set up the UITextField subclass as the target of its own Editing Changed event. This has the advantage that it doesn't prevent other objects from being the target, because a UIControl event can be sent to multiple targets.

    (Of course, I suppose you could use the UITextFieldTextDidChangeNotification instead.)