Skip to content

Instantly share code, notes, and snippets.

@NikolaiRuhe
Created September 23, 2014 10:16
Show Gist options
  • Select an option

  • Save NikolaiRuhe/bacd3f57ebb7b2c4f22b to your computer and use it in GitHub Desktop.

Select an option

Save NikolaiRuhe/bacd3f57ebb7b2c4f22b to your computer and use it in GitHub Desktop.
NRDelegateProxy is an Objective-C proxy class used for intercepting delegate callbacks.
// 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