Created
September 23, 2014 10:16
-
-
Save NikolaiRuhe/bacd3f57ebb7b2c4f22b to your computer and use it in GitHub Desktop.
NRDelegateProxy is an Objective-C proxy class used for intercepting delegate callbacks.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| // NRDelegateProxy is a base class for proxy objects that are used as intercepting | |
| // delegates in other objects. | |
| // | |
| // NRDelegateProxy is subclassed to customize delegate behavior by selectively responding | |
| // to some delegate methods while passing on other methods. It can thus be used to implement | |
| // a chain of delegates where each delegate is responsible for some specific task. | |
| // | |
| // Below is an example using a UITextField. It sets up a chain of delegates that looks as follows: | |
| // | |
| // UITextField -> NRTextFilterProxy -> NRKeyboardHiderProxy -> ViewController | |
| // | |
| // Each of the three delegates takes over some specific part in text input handling and passes | |
| // other messages along in direction of the custom view controller which sits at the end of the | |
| // chain. | |
| #import <objc/runtime.h> | |
| @interface NRDelegateProxy : NSProxy | |
| @property (nonatomic, weak) id delegate; | |
| @end | |
| @implementation NRDelegateProxy | |
| - (BOOL)respondsToSelector:(SEL)selector | |
| { | |
| // Check if the proxy (self) responds to the selector. | |
| BOOL selfResponds = class_getInstanceMethod([self class], selector) != NULL; | |
| // If not, pass on to delegate, if any. | |
| return selfResponds || [_delegate respondsToSelector:selector]; | |
| } | |
| // Fast path forwarding, circumventing expensive invocation handling | |
| - (id)forwardingTargetForSelector:(SEL)selector | |
| { | |
| return _delegate; | |
| } | |
| @end | |
| // Example delegate proxy that filters text input, simulating a broken f key. | |
| @interface NRTextFilterProxy : NRDelegateProxy <UITextFieldDelegate> | |
| @end | |
| @implementation NRTextFilterProxy | |
| - (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string | |
| { | |
| return ! [string isEqualToString:@"f"]; | |
| } | |
| @end | |
| // Example delegate proxy that hides the keyboard when pressing enter. | |
| @interface NRKeyboardHiderProxy : NRDelegateProxy <UITextFieldDelegate> | |
| @end | |
| @implementation NRKeyboardHiderProxy | |
| - (BOOL)textFieldShouldReturn:(UITextField *)textField | |
| { | |
| return [textField endEditing:NO]; | |
| } | |
| @end | |
| // Example view controller that sets up a delegate chain on its textField outlet. | |
| @interface ViewController () | |
| @property (weak, nonatomic) IBOutlet UITextField *textField; | |
| @end | |
| @implementation ViewController | |
| { | |
| NRTextFilterProxy *_textFilter; | |
| NRKeyboardHiderProxy *_keyboardHider; | |
| } | |
| - (void)viewDidLoad | |
| { | |
| if (_textFilter == nil) { | |
| _keyboardHider = [NRKeyboardHiderProxy alloc]; | |
| _keyboardHider.delegate = self; | |
| _textFilter = [NRTextFilterProxy alloc]; | |
| _textFilter.delegate = _keyboardHider; | |
| _textField.delegate = _textFilter; | |
| } | |
| [super viewDidLoad]; | |
| } | |
| - (BOOL)textFieldShouldBeginEditing:(UITextField *)textField | |
| { | |
| NSLog(@"textFieldShouldBeginEditing"); | |
| return YES; | |
| } | |
| @end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment