Skip to content

Instantly share code, notes, and snippets.

@angelolloqui
Last active December 10, 2016 21:33
Show Gist options
  • Save angelolloqui/8807330 to your computer and use it in GitHub Desktop.
Save angelolloqui/8807330 to your computer and use it in GitHub Desktop.
Basic UIResponder additions to handle commands
@interface AGCommand : NSObject
@property(nonatomic, weak) UIResponder *firingObject;
@property(nonatomic, readonly) SEL action;
+ (instancetype)command;
@end
@implementation AGCommand
+ (instancetype)command {
return [[self alloc] init];
}
- (SEL)action {
return @selector(performGenericCommand:);
}
@end
@interface UIResponder (AGCommands)
- (BOOL)canPerformCommand:(AGCommand *)command;
- (UIResponder *)targetForCommand:(AGCommand *)command;
- (BOOL)sendCommand:(AGCommand *)command;
@end
#import "UIResponder+AGCommands.h"
#import <objc/runtime.h>
@implementation UIResponder (AGCommands)
- (BOOL)canPerformCommand:(AGCommand *)command {
return [self respondsToSelector:command.action];
}
- (UIResponder *)targetForCommand:(AGCommand *)command {
UIResponder *implementor = self;
while (implementor) {
if ([implementor canPerformCommand:command] == YES) {
return implementor;
}
implementor = [implementor nextResponder];
}
return nil;
}
- (BOOL)sendCommand:(AGCommand *)command {
if (!command) return NO;
if (command.firingObject == nil) {
command.firingObject = self;
}
UIResponder *target = [self targetForCommand:command];
if (target) {
[self performCommand:command onResponder:target];
return YES;
}
return NO;
}
- (void)performCommand:(AGCommand *)command onResponder:(UIResponder *)responder {
NSInvocation *invocation = [NSInvocation invocationWithMethodSignature:[[responder class] instanceMethodSignatureForSelector:command.action]];
[invocation setSelector:command.action];
[invocation setTarget:responder];
[invocation setArgument:&command atIndex:2];
[invocation invoke];
}
@end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment