Reputation: 4016
I'm trying to create a text field that would be able to respond to the following:
-(BOOL)textFieldShouldEndEditing:(UITextField *)textField
To do so i have a UITextField subclass which is a delegate for itself:
[self setDelegate:self]
QUESTION: What would be the easiest way to implement delegate methods in a subclass, but still allowing an outside object to be a delegate as well and recieve the same messages?
Thanks
Upvotes: 6
Views: 4739
Reputation: 19339
I was having the exact same issue (in Swift 3). I solved the problem overriding the delegate
property from the UITextField
class.
During my custom view initialization, I hook up my own internal delegate:
class CustomTextField: UITextField, UITextFieldDelegate {
override public init(frame: CGRect) {
super.init(frame: frame)
initCustomTextField()
}
required public init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
initCustomTextField()
}
private func initCustomTextField() {
super.delegate = self // Note the super qualifier.
}
...
Now we need to override the aforementioned delegate
property:
private weak var userDelegate: UITextFieldDelegate?
override var delegate: UITextFieldDelegate? {
get { return userDelegate }
set { userDelegate = newValue }
}
Finally, on each UITextFieldDelegate
protocol method you must forward the call to the external delegate, if any:
func textFieldShouldBeginEditing(_ textField: UITextField) -> Bool {
// Do your thing here, and then forward:
return self.delegate?.textFieldShouldBeginEditing?(self) ?? true
}
func textFieldDidBeginEditing(_ textField: UITextField) {
// Do your thing here, and then forward:
self.delegate?.textFieldDidBeginEditing?(self)
}
...
One caveat if you plan to support iOS 10 as well:
func textFieldDidEndEditing(_ textField: UITextField) {
self.delegate?.textFieldDidEndEditing?(self)
}
/// This method will be called, instead of the above, on iOS ≥ 10.
@available(iOS 10.0, *)
func textFieldDidEndEditing(_ textField: UITextField, reason: UITextFieldDidEndEditingReason) {
self.delegate?.textFieldDidEndEditing?(self, reason: reason)
}
Upvotes: 15
Reputation: 4005
For creating you own delegate you need to define new protocol into your subclass
@protocol MyUItestFieldDelegate <NSObject>
- (void)customUITextFieldDelegateMethod;
@end
which you can use into your controller like
@interface MyViewController : UIViewController <MyUItestFieldDelegate>
Upvotes: 0
Reputation: 3017
You can make use of Notifications
.
Make it that text field post notification, like the following:
[[NSNotificationCenter defaultCenter] postNotificationName:@"custom notification name" object:self];
and add observer to the class which is supposed to be external delegate:
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(cacheUpdated:) name:@"custom notification name" object:nil];
That way, text field post notification which means it took a certain action and your external delegate class will be notified since it's already been listening to that kind of notifications. Hope it helps.
Upvotes: 0