I have subclassed the UITextField class so I can provide some built-in functionality for my application. I've changed the appearance to provide only an underline border for the UX design. Also, I want to use this control in situations where there is a picker (pick list, date / time picker). In these cases, I want to prevent editing BUT I still need to respond to touch events. To do this, I've added inspectable properties to control it from IB.
I can easily prevent the copy/paste menu from appearing by doing this:
override func canPerformAction(_ action: Selector, withSender sender: Any?) -> Bool {
if isFirstResponder && disableEditing {
DispatchQueue.main.async(execute: {
(sender as? UIMenuController)?.setMenuVisible(false, animated: false)
})
return false
}
return super.canPerformAction(action, withSender: sender)
}
However, I need to prevent them from typing or deleting characters in the textfield after something is selected in the picker. Typically, you would use the following delegate method:
func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {
return false
}
The question is how do you provide this kind of default behavior in a subclass? You could do a:
self.delegate = self
However, this leads to all sorts of shortcomings so it's not a good solution.
The other solution would be to implement a base UIViewController subclass (MyBaseViewController) but this would lead to convoluted and monolithic code later on.
It would be best if there was a clean way to provide this kind of default behavior in an encapsulated manner.
Obviously, there are a number of other ways to fix this (i.e. write the same code in 10 view controllers). Essentially, it seems there should be way to reuse delegate code when subclassing controls like this.
Anyone have any ideas??