Skip to content

Instantly share code, notes, and snippets.

@futuretap
Created September 14, 2016 18:18
Show Gist options
  • Star 6 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save futuretap/d0978e623e7fce9b430767f503fdc10c to your computer and use it in GitHub Desktop.
Save futuretap/d0978e623e7fce9b430767f503fdc10c to your computer and use it in GitHub Desktop.
Block based interface to UIKeyCommand
//
// UIResponder+FTAdditions.h
// Streets
//
// Created by Ortwin Gentz on 09.05.16.
// Copyright © 2016 FutureTap. All rights reserved.
//
#import <UIKit/UIKit.h>
@interface FTKeyCommand : NSObject <NSObject>
+ (instancetype)keyCommandWithInput:(NSString *)input modifierFlags:(UIKeyModifierFlags)modifierFlags discoverabilityTitle:(NSString *)discoverabilityTitle block:(void(^)())block;
@property (nonatomic) NSString *input;
@property (nonatomic) UIKeyModifierFlags modifierFlags;
@property (nonatomic) NSString *discoverabilityTitle;
@property (nonatomic) void (^block)();
@end
@interface UIResponder (FTAdditions)
@property (nonatomic) NSArray *ftKeyCommands;
@end
//
// UIResponder+FTAdditions.m
// Streets
//
// Created by Ortwin Gentz on 09.05.16.
// Copyright © 2016 FutureTap. All rights reserved.
//
#import <objc/runtime.h>
#import "UIResponder+FTAdditions.h"
#import "MethodSwizzling.h"
#import "NSArray+Additions.h"
#import "UIDevice+Additions.h"
@implementation FTKeyCommand
+ (instancetype)keyCommandWithInput:(NSString *)input modifierFlags:(UIKeyModifierFlags)modifierFlags discoverabilityTitle:(NSString *)discoverabilityTitle block:(void(^)())block {
FTKeyCommand *keyCommand = [[self alloc] init];
keyCommand.input = input;
keyCommand.modifierFlags = modifierFlags;
keyCommand.discoverabilityTitle = discoverabilityTitle;
keyCommand.block = block;
return keyCommand;
}
- (BOOL)isEqual:(FTKeyCommand*)keyCommand {
return [self.input isEqual:keyCommand.input] && self.modifierFlags == keyCommand.modifierFlags;
}
@end
@implementation UIResponder (FTAdditions)
+ (void)load {
Swizzle(self, @selector(canBecomeFirstResponder), @selector(myCanBecomeFirstResponder));
Swizzle(self, @selector(keyCommands), @selector(myKeyCommands));
}
static char ftKeyCommandsKey;
- (void)setFtKeyCommands:(NSArray *)ftKeyCommands {
objc_setAssociatedObject(self, &ftKeyCommandsKey, ftKeyCommands, OBJC_ASSOCIATION_RETAIN);
}
- (NSArray*)ftKeyCommands {
return objc_getAssociatedObject(self, &ftKeyCommandsKey);
}
- (NSArray*)myKeyCommands {
if (self.ftKeyCommands) {
NSArray *keyCommands = [self.ftKeyCommands mapObjectsUsingBlock:^id(FTKeyCommand *keyCommand, NSUInteger idx) {
if ([UIKeyCommand respondsToSelector:@selector(keyCommandWithInput:modifierFlags:action:discoverabilityTitle:)]) {
return [UIKeyCommand keyCommandWithInput:keyCommand.input modifierFlags:keyCommand.modifierFlags action:@selector(ftPerformKeyCommand:)];
}
return [UIKeyCommand keyCommandWithInput:keyCommand.input modifierFlags:keyCommand.modifierFlags action:@selector(ftPerformKeyCommand:)];
}];
return keyCommands;
} else {
return [self myKeyCommands];
}
}
- (void)ftPerformKeyCommand:(UIKeyCommand*)keyCommand {
FTKeyCommand *ftKkeyCommand = [self.ftKeyCommands selectFirstObjectUsingBlock:^BOOL(FTKeyCommand *testKeyCommand) {
return [testKeyCommand isEqual:keyCommand];
}];
if (ftKkeyCommand) {
ftKkeyCommand.block();
}
}
- (BOOL)myCanBecomeFirstResponder {
return self.ftKeyCommands.count ?: [self myCanBecomeFirstResponder];
}
@end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment