Skip to content

Commit f7659a8

Browse files
committed
Add keyboard shortcuts support when using UIKit for Mac (Project Catalyst)
Fixes #297.
1 parent 85cc51b commit f7659a8

5 files changed

+152
-6
lines changed

Classes/FLEXManager.h

+7
Original file line numberDiff line numberDiff line change
@@ -88,4 +88,11 @@ typedef UIViewController *(^FLEXCustomContentViewerFuture)(NSData *data);
8888
- (void)setCustomViewerForContentType:(NSString *)contentType
8989
viewControllerFutureBlock:(FLEXCustomContentViewerFuture)viewControllerFutureBlock;
9090

91+
#if TARGET_OS_MACCATALYST
92+
93+
/// Gets the default and custom keyboard shortcuts commands.
94+
- (NSArray<UIKeyCommand *> *)getKeyCommands;
95+
96+
#endif
97+
9198
@end

Classes/Manager/FLEXManager.m

+12-3
Original file line numberDiff line numberDiff line change
@@ -153,21 +153,21 @@ - (void)explorerViewControllerDidFinish:(FLEXExplorerViewController *)explorerVi
153153

154154
- (void)registerSimulatorShortcutWithKey:(NSString *)key modifiers:(UIKeyModifierFlags)modifiers action:(dispatch_block_t)action description:(NSString *)description
155155
{
156-
# if TARGET_OS_SIMULATOR
156+
# if TARGET_OS_SIMULATOR || TARGET_OS_MACCATALYST
157157
[[FLEXKeyboardShortcutManager sharedManager] registerSimulatorShortcutWithKey:key modifiers:modifiers action:action description:description];
158158
#endif
159159
}
160160

161161
- (void)setSimulatorShortcutsEnabled:(BOOL)simulatorShortcutsEnabled
162162
{
163-
# if TARGET_OS_SIMULATOR
163+
# if TARGET_OS_SIMULATOR || TARGET_OS_MACCATALYST
164164
[[FLEXKeyboardShortcutManager sharedManager] setEnabled:simulatorShortcutsEnabled];
165165
#endif
166166
}
167167

168168
- (BOOL)simulatorShortcutsEnabled
169169
{
170-
# if TARGET_OS_SIMULATOR
170+
# if TARGET_OS_SIMULATOR || TARGET_OS_MACCATALYST
171171
return [[FLEXKeyboardShortcutManager sharedManager] isEnabled];
172172
#else
173173
return NO;
@@ -378,4 +378,13 @@ - (void)showExplorerIfNeeded
378378
}
379379
}
380380

381+
#if TARGET_OS_MACCATALYST
382+
383+
- (NSArray<UIKeyCommand *> *)getKeyCommands {
384+
385+
return [[FLEXKeyboardShortcutManager sharedManager] getKeyCommands];
386+
}
387+
388+
#endif
389+
381390
@end

Classes/Utility/FLEXKeyboardHelpViewController.m

+1-1
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ - (void)viewDidLoad
2424
self.textView = [[UITextView alloc] initWithFrame:self.view.bounds];
2525
self.textView.autoresizingMask = UIViewAutoresizingFlexibleWidth|UIViewAutoresizingFlexibleHeight;
2626
[self.view addSubview:self.textView];
27-
#if TARGET_OS_SIMULATOR
27+
#if TARGET_OS_SIMULATOR || TARGET_OS_MACCATALYST
2828
self.textView.text = [[FLEXKeyboardShortcutManager sharedManager] keyboardShortcutsDescription];
2929
#endif
3030
self.textView.backgroundColor = [UIColor blackColor];

Classes/Utility/FLEXKeyboardShortcutManager.h

+7-1
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88

99
#import <UIKit/UIKit.h>
1010

11-
#if TARGET_OS_SIMULATOR
11+
#if TARGET_OS_SIMULATOR || TARGET_OS_MACCATALYST
1212

1313
@interface FLEXKeyboardShortcutManager : NSObject
1414

@@ -19,6 +19,12 @@
1919

2020
@property (nonatomic, assign, getter=isEnabled) BOOL enabled;
2121

22+
#if TARGET_OS_MACCATALYST
23+
24+
- (NSArray<UIKeyCommand *> *)getKeyCommands;
25+
26+
#endif
27+
2228
@end
2329

2430
#endif

Classes/Utility/FLEXKeyboardShortcutManager.m

+125-1
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
#import <objc/runtime.h>
1212
#import <objc/message.h>
1313

14-
#if TARGET_OS_SIMULATOR
14+
#if TARGET_OS_SIMULATOR || TARGET_OS_MACCATALYST
1515

1616
@interface UIEvent (UIPhysicalKeyboardEvent)
1717

@@ -23,21 +23,109 @@ @interface UIEvent (UIPhysicalKeyboardEvent)
2323

2424
@end
2525

26+
#if TARGET_OS_MACCATALYST
27+
28+
@interface FLEXKeyInput : UIKeyCommand
29+
30+
@end
31+
32+
@interface UIKeyCommand (FLEX)
33+
34+
@property (nonatomic, assign, readonly) BOOL isCreatedByFLEX;
35+
36+
#else
37+
2638
@interface FLEXKeyInput : NSObject <NSCopying>
2739

40+
#endif
41+
2842
@property (nonatomic, copy, readonly) NSString *key;
2943
@property (nonatomic, assign, readonly) UIKeyModifierFlags flags;
3044
@property (nonatomic, copy, readonly) NSString *helpDescription;
3145

3246
@end
3347

48+
#if TARGET_OS_MACCATALYST
49+
50+
@implementation FLEXKeyInput
51+
52+
@end
53+
54+
@implementation UIKeyCommand (FLEX)
55+
56+
- (NSString *)key {
57+
58+
return objc_getAssociatedObject(self, @selector(key));
59+
}
60+
61+
- (void)setKey:(NSString *)key {
62+
63+
objc_setAssociatedObject(self, @selector(key), key, OBJC_ASSOCIATION_COPY_NONATOMIC);
64+
}
65+
66+
- (UIKeyModifierFlags)flags {
67+
68+
UIKeyModifierFlags (^block)() = objc_getAssociatedObject(self, @selector(flags));
69+
70+
return (block ? block() : kNilOptions);
71+
}
72+
73+
- (void)setFlags:(UIKeyModifierFlags)flags {
74+
75+
UIKeyModifierFlags (^block)() = ^{
76+
return flags;
77+
};
78+
79+
objc_setAssociatedObject(self, @selector(flags), block, OBJC_ASSOCIATION_COPY);
80+
}
81+
82+
- (NSString *)helpDescription {
83+
84+
return objc_getAssociatedObject(self, @selector(helpDescription));
85+
}
86+
87+
- (void)setHelpDescription:(NSString *)helpDescription {
88+
89+
objc_setAssociatedObject(self, @selector(helpDescription), helpDescription, OBJC_ASSOCIATION_COPY_NONATOMIC);
90+
}
91+
92+
- (BOOL)isCreatedByFLEX {
93+
94+
BOOL (^block)() = objc_getAssociatedObject(self, @selector(isCreatedByFLEX));
95+
96+
return (block ? block() : NO);
97+
}
98+
99+
- (void)setIsCreatedByFLEX:(BOOL)isCreatedByFLEX {
100+
101+
BOOL (^block)() = ^{
102+
return isCreatedByFLEX;
103+
};
104+
105+
objc_setAssociatedObject(self, @selector(isCreatedByFLEX), block, OBJC_ASSOCIATION_COPY);
106+
}
107+
108+
#else
109+
34110
@implementation FLEXKeyInput
35111

112+
#endif
113+
36114
- (BOOL)isEqual:(id)object
37115
{
38116
BOOL isEqual = NO;
117+
#if TARGET_OS_MACCATALYST
118+
if ([object isKindOfClass:[UIKeyCommand class]]) {
119+
UIKeyCommand *keyCommand = (UIKeyCommand *)object;
120+
if (!keyCommand.isCreatedByFLEX) {
121+
// Not FLEX's business anymore.
122+
123+
return [super isEqual:object];
124+
}
125+
#else
39126
if ([object isKindOfClass:[FLEXKeyInput class]]) {
40127
FLEXKeyInput *keyCommand = (FLEXKeyInput *)object;
128+
#endif
41129
BOOL equalKeys = self.key == keyCommand.key || [self.key isEqual:keyCommand.key];
42130
BOOL equalFlags = self.flags == keyCommand.flags;
43131
isEqual = equalKeys && equalFlags;
@@ -98,6 +186,23 @@ + (instancetype)keyInputForKey:(NSString *)key flags:(UIKeyModifierFlags)flags
98186
return [self keyInputForKey:key flags:flags helpDescription:nil];
99187
}
100188

189+
#if TARGET_OS_MACCATALYST
190+
191+
+ (instancetype)keyInputForKey:(NSString *)key flags:(UIKeyModifierFlags)flags helpDescription:(NSString *)helpDescription
192+
{
193+
FLEXKeyInput *keyInput = [UIKeyCommand keyCommandWithInput:key modifierFlags:flags action:nil];
194+
if (keyInput) {
195+
[keyInput setKey:key];
196+
[keyInput setFlags:flags];
197+
[keyInput setHelpDescription:helpDescription];
198+
199+
[keyInput setIsCreatedByFLEX:YES];
200+
}
201+
return keyInput;
202+
}
203+
204+
#else
205+
101206
+ (instancetype)keyInputForKey:(NSString *)key flags:(UIKeyModifierFlags)flags helpDescription:(NSString *)helpDescription
102207
{
103208
FLEXKeyInput *keyInput = [[self alloc] init];
@@ -109,12 +214,22 @@ + (instancetype)keyInputForKey:(NSString *)key flags:(UIKeyModifierFlags)flags h
109214
return keyInput;
110215
}
111216

217+
#endif
218+
112219
@end
113220

114221
@interface FLEXKeyboardShortcutManager ()
115222

223+
#if TARGET_OS_MACCATALYST
224+
225+
@property (nonatomic, strong) NSMutableDictionary<UIKeyCommand *, dispatch_block_t> *actionsForKeyInputs;
226+
227+
#else
228+
116229
@property (nonatomic, strong) NSMutableDictionary<FLEXKeyInput *, dispatch_block_t> *actionsForKeyInputs;
117230

231+
#endif
232+
118233
@property (nonatomic, assign, getter=isPressingShift) BOOL pressingShift;
119234
@property (nonatomic, assign, getter=isPressingCommand) BOOL pressingCommand;
120235
@property (nonatomic, assign, getter=isPressingControl) BOOL pressingControl;
@@ -305,6 +420,15 @@ - (NSString *)keyboardShortcutsDescription
305420
return [description copy];
306421
}
307422

423+
#if TARGET_OS_MACCATALYST
424+
425+
- (NSArray<UIKeyCommand *> *)getKeyCommands {
426+
427+
return self.actionsForKeyInputs.allKeys;
428+
}
429+
430+
#endif
431+
308432
@end
309433

310434
#endif

0 commit comments

Comments
 (0)