react-native-external-keyboard 0.6.2 → 0.6.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -18,7 +18,9 @@
18
18
  - (NSString*_Nonnull) getFocusGroupIdentifier;
19
19
  - (void)updateGroupIdentifier;
20
20
  - (void)clear;
21
- - (void)clearSubview: (UIView*_Nullable)view;
21
+ - (void)clearSubview:(UIView*_Nullable)subview;
22
+ - (void)syncCustomGroupId;
23
+
22
24
  @end
23
25
 
24
26
 
@@ -10,6 +10,11 @@
10
10
  #import "RNCEKVGroupIdentifierDelegate.h"
11
11
  #import "RNCEKVFocusEffectUtility.h"
12
12
 
13
+ #ifdef RCT_NEW_ARCH_ENABLED
14
+ #import "RCTViewComponentView+RNCEKVExternalKeyboard.h"
15
+ #endif
16
+
17
+
13
18
  @implementation RNCEKVGroupIdentifierDelegate {
14
19
  UIView<RNCEKVGroupIdentifierProtocol>* _delegate;
15
20
  NSString* _tagId;
@@ -24,48 +29,89 @@
24
29
  }
25
30
 
26
31
 
27
- - (NSString*) getFocusGroupIdentifier {
28
- if(_delegate.customGroupId) {
29
- return _delegate.customGroupId;
30
- }
31
-
32
+ - (NSString*) getTagId {
32
33
  if(_tagId) {
33
34
  return _tagId;
34
35
  }
35
-
36
+
36
37
  NSUUID *uuid = [NSUUID UUID];
37
38
  NSString *uniqueID = [uuid UUIDString];
38
39
  _tagId = [NSString stringWithFormat:@"app.group.%@", uniqueID];
39
-
40
+
40
41
  return _tagId;
41
42
  }
42
43
 
43
44
 
45
+ - (NSString*) getFocusGroupIdentifier {
46
+ if (@available(iOS 14.0, *)) {
47
+ if(_delegate.customGroupId) {
48
+ return _delegate.customGroupId;
49
+ }
50
+
51
+ return [self getTagId];
52
+ } else {
53
+ return nil;
54
+ }
55
+ }
56
+
57
+
58
+ #ifdef RCT_NEW_ARCH_ENABLED
44
59
  - (void) updateGroupIdentifier {
45
60
  if (@available(iOS 14.0, *)) {
46
- UIView* focusView = [_delegate getFocusTargetView];
47
- if(focusView) {
48
- focusView.focusGroupIdentifier = [self getFocusGroupIdentifier];
61
+ UIView* focus = [_delegate getFocusTargetView];
62
+
63
+ NSString* identifier = [self getFocusGroupIdentifier];
64
+ if([focus isKindOfClass:[RCTViewComponentView class]]) {
65
+ ((RCTViewComponentView*)focus).rncekvCustomGroup = identifier;
66
+ } else {
67
+ focus.focusGroupIdentifier = identifier;
49
68
  }
50
69
  }
51
70
  }
52
71
 
72
+ #else
73
+
74
+ - (void) updateGroupIdentifier {
75
+ if (@available(iOS 14.0, *)) {
76
+ UIView* focus = [_delegate getFocusTargetView];
77
+ focus.focusGroupIdentifier = [self getFocusGroupIdentifier];
78
+ }
79
+ }
80
+
81
+ #endif
82
+
53
83
  - (void) clear {
54
- _tagId = nil;
55
84
  if (@available(iOS 14.0, *)) {
56
- UIView* focusView = [_delegate getFocusTargetView];
57
- if(focusView) {
58
- focusView.focusGroupIdentifier = nil;
59
- }
85
+ UIView* focus = [_delegate getFocusTargetView];
86
+ [self clearSubview: focus];
60
87
  }
61
88
  }
62
89
 
63
- - (void)clearSubview: (UIView*_Nullable)view {
90
+ #ifdef RCT_NEW_ARCH_ENABLED
91
+ - (void)clearSubview: (UIView*_Nullable)subview {
92
+ if(!subview) return;
93
+
64
94
  if (@available(iOS 14.0, *)) {
65
- _tagId = nil;
66
- if(view.focusGroupIdentifier != nil) {
67
- view.focusGroupIdentifier = nil;
95
+
96
+ if(subview) {
97
+ if([subview isKindOfClass:[RCTViewComponentView class]]) {
98
+ ((RCTViewComponentView*)subview).rncekvCustomGroup = nil;
99
+ } else {
100
+ subview.focusGroupIdentifier = nil;
101
+ }
68
102
  }
69
103
  }
70
104
  }
105
+ #else
106
+
107
+ - (void)clearSubview: (UIView*_Nullable)subview {
108
+ if(!subview) return;
109
+
110
+ if (@available(iOS 14.0, *)) {
111
+ subview.focusGroupIdentifier = nil;
112
+ }
113
+ }
114
+
115
+ #endif
116
+
71
117
  @end
@@ -0,0 +1,20 @@
1
+ //
2
+ // UIView+RNCEKVExternalKeyboard.h
3
+ // Pods
4
+ //
5
+ // Created by Artur Kalach on 12/08/2025.
6
+ //
7
+
8
+ #ifndef UIView_RNCEKVExternalKeyboard_h
9
+ #define UIView_RNCEKVExternalKeyboard_h
10
+
11
+ #import <React/RCTViewComponentView.h>
12
+
13
+ @interface RCTViewComponentView (RNCEKVExternalKeyboard)
14
+
15
+ @property (nonatomic, copy, nullable) NSString *rncekvCustomGroup;
16
+
17
+ @end
18
+
19
+
20
+ #endif /* UIView_RNCEKVExternalKeyboard_h */
@@ -0,0 +1,34 @@
1
+ //
2
+ // UIView+RNCEKVExternalKeyboard.m
3
+ // react-native-external-keyboard
4
+ //
5
+ // Created by Artur Kalach on 12/08/2025.
6
+ //
7
+
8
+ #import <Foundation/Foundation.h>
9
+
10
+ #import "RCTViewComponentView+RNCEKVExternalKeyboard.h"
11
+
12
+ #import <objc/runtime.h>
13
+ static const void *RNCEKVCustomGroupKey = &RNCEKVCustomGroupKey;
14
+
15
+ @implementation RCTViewComponentView (RNCEKVExternalKeyboard)
16
+
17
+ - (NSString *)rncekvCustomGroup {
18
+ return objc_getAssociatedObject(self, RNCEKVCustomGroupKey);
19
+ }
20
+
21
+ // Setter for `rctekvCustomGroup`
22
+ - (void)setRncekvCustomGroup:(NSString *)rncekvCustomGroup {
23
+ objc_setAssociatedObject(self, RNCEKVCustomGroupKey, rncekvCustomGroup, OBJC_ASSOCIATION_COPY_NONATOMIC);
24
+ }
25
+
26
+ - (NSString *)focusGroupIdentifier {
27
+ NSString* rncekv = [self rncekvCustomGroup];
28
+ if(rncekv) {
29
+ return rncekv;
30
+ }
31
+ return [super focusGroupIdentifier];
32
+ }
33
+
34
+ @end
@@ -8,7 +8,7 @@
8
8
  #import "RNCEKVGroupIdentifierProtocol.h"
9
9
 
10
10
  #ifdef RCT_NEW_ARCH_ENABLED
11
- #import <React/RCTViewComponentView.h>
11
+ #import "RCTViewComponentView+RNCEKVExternalKeyboard.h"
12
12
 
13
13
  NS_ASSUME_NONNULL_BEGIN
14
14
 
@@ -37,7 +37,7 @@ using namespace facebook::react;
37
37
  RNCEKVFocusDelegate *_focusDelegate;
38
38
  RNCEKVGroupIdentifierDelegate *_gIdDelegate;
39
39
  RNCEKVFocusOrderDelegate *_focusOrderDelegate;
40
-
40
+
41
41
  NSNumber *_isFocused;
42
42
  BOOL _isAttachedToWindow;
43
43
  BOOL _isAttachedToController;
@@ -61,16 +61,12 @@ using namespace facebook::react;
61
61
  if(_orderPosition != nil && _orderGroup != nil && _isLinked) {
62
62
  [[RNCEKVOrderLinking sharedInstance] remove:_orderPosition withOrderKey: _orderGroup];
63
63
  }
64
-
64
+
65
65
  if(_orderId != nil) {
66
66
  [[RNCEKVOrderLinking sharedInstance] cleanOrderId:_orderId];
67
67
  [_focusOrderDelegate clear];
68
68
  }
69
-
70
- if (_customGroupId && _gIdDelegate) {
71
- [_gIdDelegate clear];
72
- }
73
-
69
+
74
70
  _isLinked = NO;
75
71
  _isIdLinked = NO;
76
72
  }
@@ -130,14 +126,14 @@ using namespace facebook::react;
130
126
  _focusDelegate = [[RNCEKVFocusDelegate alloc] initWithView:self];
131
127
  _gIdDelegate = [[RNCEKVGroupIdentifierDelegate alloc] initWithView:self];
132
128
  _focusOrderDelegate = [[RNCEKVFocusOrderDelegate alloc] initWithView: self];
133
-
129
+
134
130
  if (@available(iOS 13.0, *)) {
135
131
  UIContextMenuInteraction *interaction =
136
132
  [[UIContextMenuInteraction alloc] initWithDelegate:self];
137
133
  [self addInteraction:interaction];
138
134
  }
139
135
  }
140
-
136
+
141
137
  return self;
142
138
  }
143
139
 
@@ -166,7 +162,6 @@ using namespace facebook::react;
166
162
  _customGroupId = nil;
167
163
  _enableA11yFocus = NO;
168
164
  _isLinked = NO;
169
- self.focusGroupIdentifier = nil;
170
165
  }
171
166
 
172
167
  - (void)setOrderGroup:(NSString *)orderGroup{
@@ -189,12 +184,12 @@ using namespace facebook::react;
189
184
  if(!_orderGroup && !_orderPosition && !_lockFocus && !_orderForward && !_orderBackward) {
190
185
  return [super shouldUpdateFocusInContext: context];
191
186
  }
192
-
187
+
193
188
  NSNumber* result = [_focusOrderDelegate shouldUpdateFocusInContext: context];
194
189
  if(result == nil) {
195
190
  return [super shouldUpdateFocusInContext: context];
196
191
  }
197
-
192
+
198
193
  return result.boolValue;
199
194
  }
200
195
 
@@ -205,7 +200,7 @@ using namespace facebook::react;
205
200
  }
206
201
  _orderPosition = position;
207
202
  }
208
-
203
+
209
204
  if(_orderPosition == nil && _orderPosition != position) {
210
205
  _orderPosition = position;
211
206
  }
@@ -237,41 +232,41 @@ using namespace facebook::react;
237
232
  const auto &newViewProps =
238
233
  *std::static_pointer_cast<ExternalKeyboardViewProps const>(props);
239
234
  [super updateProps:props oldProps:oldProps];
240
-
235
+
241
236
  if (_hasOnFocusChanged != newViewProps.hasOnFocusChanged) {
242
237
  [self setHasOnFocusChanged:newViewProps.hasOnFocusChanged];
243
238
  }
244
-
239
+
245
240
  BOOL isLockChanged = [RNCEKVPropHelper isPropChanged:_lockFocus intValue: newViewProps.lockFocus];
246
241
  if(isLockChanged) {
247
242
  NSNumber* lockValue = [RNCEKVPropHelper unwrapIntValue: newViewProps.lockFocus];
248
243
  [self setLockFocus: lockValue];
249
244
  }
250
-
245
+
251
246
  if (oldViewProps.canBeFocused != newViewProps.canBeFocused) {
252
247
  [self setCanBeFocused:newViewProps.canBeFocused];
253
248
  }
254
-
249
+
255
250
  if (oldViewProps.hasKeyUpPress != newViewProps.hasKeyUpPress) {
256
251
  [self setHasOnPressUp:newViewProps.hasKeyUpPress];
257
252
  }
258
-
253
+
259
254
  if (oldViewProps.hasKeyDownPress != newViewProps.hasKeyDownPress) {
260
255
  [self setHasOnPressDown:newViewProps.hasKeyDownPress];
261
256
  }
262
-
257
+
263
258
  if (oldViewProps.autoFocus != newViewProps.autoFocus) {
264
259
  BOOL hasAutoFocus = newViewProps.autoFocus;
265
260
  [self setAutoFocus:hasAutoFocus];
266
261
  }
267
-
268
-
262
+
263
+
269
264
  BOOL isIndexChanged = [RNCEKVPropHelper isPropChanged:_orderPosition intValue: newViewProps.orderIndex];
270
265
  if(isIndexChanged) {
271
266
  NSNumber* position = [RNCEKVPropHelper unwrapIntValue: newViewProps.orderIndex];
272
267
  [self updateOrderPosition: position];
273
268
  }
274
-
269
+
275
270
  RKNA_PROP_UPDATE(orderGroup, setOrderGroup, newViewProps);
276
271
  RKNA_PROP_UPDATE(orderId, setOrderId, newViewProps);
277
272
  RKNA_PROP_UPDATE(orderLeft, setOrderLeft, newViewProps);
@@ -282,22 +277,22 @@ using namespace facebook::react;
282
277
  RKNA_PROP_UPDATE(orderBackward, setOrderBackward, newViewProps);
283
278
  RKNA_PROP_UPDATE(orderLast, setOrderLast, newViewProps);
284
279
  RKNA_PROP_UPDATE(orderFirst, setOrderFirst, newViewProps);
285
-
280
+
286
281
  if (_enableA11yFocus != newViewProps.enableA11yFocus) {
287
282
  [self setEnableA11yFocus:newViewProps.enableA11yFocus];
288
283
  }
289
-
284
+
290
285
  UIColor *newColor = RCTUIColorFromSharedColor(newViewProps.tintColor);
291
286
  BOOL renewColor = newColor != nil && self.tintColor == nil;
292
287
  BOOL isColorChanged = oldViewProps.tintColor != newViewProps.tintColor;
293
288
  if (isColorChanged || renewColor) {
294
289
  self.tintColor = RCTUIColorFromSharedColor(newViewProps.tintColor);
295
290
  }
296
-
291
+
297
292
  if (oldViewProps.group != newViewProps.group) {
298
293
  [self setIsGroup:newViewProps.group];
299
294
  }
300
-
295
+
301
296
  BOOL isNewGroup =
302
297
  oldViewProps.groupIdentifier != newViewProps.groupIdentifier;
303
298
  BOOL recoverCustomGroup =
@@ -312,7 +307,7 @@ using namespace facebook::react;
312
307
  [self setCustomGroupId:newGroupId];
313
308
  }
314
309
  }
315
-
310
+
316
311
  // ToDo RNCEKV-0, refactor, condition for halo effect has side effect, recycle
317
312
  // is a question. The problem that we have to check the condition, (true means
318
313
  // we skip, but when it was false we should reset) and recycle (view is reused
@@ -324,25 +319,20 @@ using namespace facebook::react;
324
319
  [self setIsHaloActive:@(haloState)];
325
320
  }
326
321
  }
327
-
322
+
328
323
  if (_haloExpendX != newViewProps.haloExpendX) {
329
324
  [self setHaloExpendX:newViewProps.haloExpendX];
330
325
  }
331
-
326
+
332
327
  if (_haloExpendY != newViewProps.haloExpendY) {
333
328
  [self setHaloExpendY:newViewProps.haloExpendY];
334
329
  }
335
-
330
+
336
331
  if (_haloCornerRadius != newViewProps.haloCornerRadius) {
337
332
  [self setHaloCornerRadius:newViewProps.haloCornerRadius];
338
333
  }
339
334
  }
340
335
 
341
- - (void)mountChildComponentView:
342
- (UIView<RCTComponentViewProtocol> *)childComponentView
343
- index:(NSInteger)index {
344
- [super mountChildComponentView:childComponentView index:index];
345
- }
346
336
 
347
337
  Class<RCTComponentViewProtocol> ExternalKeyboardViewCls(void) {
348
338
  return RNCEKVExternalKeyboardView.class;
@@ -375,7 +365,7 @@ Class<RCTComponentViewProtocol> ExternalKeyboardViewCls(void) {
375
365
 
376
366
  - (void)updateFocus:(UIViewController *)controller {
377
367
  UIView *focusingView = self; // [_focusDelegate getFocusingView];
378
-
368
+
379
369
  if (self.superview != nil && controller != nil) {
380
370
  controller.customFocusView = focusingView;
381
371
  dispatch_async(dispatch_get_main_queue(), ^{
@@ -389,7 +379,7 @@ Class<RCTComponentViewProtocol> ExternalKeyboardViewCls(void) {
389
379
  - (void)didUpdateFocusInContext:(UIFocusUpdateContext *)context
390
380
  withAnimationCoordinator:(UIFocusAnimationCoordinator *)coordinator {
391
381
  _isFocused = [_focusDelegate isFocusChanged:context];
392
-
382
+
393
383
  [_focusOrderDelegate setIsFocused: [_isFocused isEqual:@YES]];
394
384
  if ([self hasOnFocusChanged]) {
395
385
  if (_isFocused != nil) {
@@ -397,10 +387,10 @@ Class<RCTComponentViewProtocol> ExternalKeyboardViewCls(void) {
397
387
  _isAttachedToController = YES;
398
388
  [self onFocusChangeHandler:[_isFocused isEqual:@YES]];
399
389
  }
400
-
390
+
401
391
  return;
402
392
  }
403
-
393
+
404
394
  [super didUpdateFocusInContext:context withAnimationCoordinator:coordinator];
405
395
  }
406
396
 
@@ -475,11 +465,11 @@ Class<RCTComponentViewProtocol> ExternalKeyboardViewCls(void) {
475
465
  withEvent:(UIPressesEvent *)event {
476
466
  NSDictionary *eventInfo = [_keyboardKeyPressHandler actionDownHandler:presses
477
467
  withEvent:event];
478
-
468
+
479
469
  if (self.hasOnPressUp || self.hasOnPressDown) {
480
470
  [self onKeyDownPressHandler:eventInfo];
481
471
  }
482
-
472
+
483
473
  [super pressesBegan:presses withEvent:event];
484
474
  }
485
475
 
@@ -487,11 +477,11 @@ Class<RCTComponentViewProtocol> ExternalKeyboardViewCls(void) {
487
477
  withEvent:(UIPressesEvent *)event {
488
478
  NSDictionary *eventInfo = [_keyboardKeyPressHandler actionUpHandler:presses
489
479
  withEvent:event];
490
-
480
+
491
481
  if (self.hasOnPressUp || self.hasOnPressDown) {
492
482
  [self onKeyUpPressHandler:eventInfo];
493
483
  }
494
-
484
+
495
485
  [super pressesEnded:presses withEvent:event];
496
486
  }
497
487
 
@@ -523,8 +513,9 @@ Class<RCTComponentViewProtocol> ExternalKeyboardViewCls(void) {
523
513
 
524
514
  - (void)didMoveToWindow {
525
515
  [super didMoveToWindow];
526
-
516
+
527
517
  if (self.window) {
518
+ [_gIdDelegate updateGroupIdentifier];
528
519
  [[NSNotificationCenter defaultCenter]
529
520
  addObserver:self
530
521
  selector:@selector(viewControllerChanged:)
@@ -538,7 +529,7 @@ Class<RCTComponentViewProtocol> ExternalKeyboardViewCls(void) {
538
529
  object:nil];
539
530
  [self onDetached];
540
531
  }
541
-
532
+
542
533
  if (self.window && !_isAttachedToWindow) {
543
534
  [self onViewAttached];
544
535
  _isAttachedToWindow = YES;
@@ -556,21 +547,26 @@ Class<RCTComponentViewProtocol> ExternalKeyboardViewCls(void) {
556
547
  - (void)layoutSubviews {
557
548
  [super layoutSubviews];
558
549
  [_haloDelegate displayHalo];
559
-
550
+ }
551
+
552
+
553
+ - (void) setCustomGroupId:(NSString *)customGroupId {
554
+ _customGroupId = customGroupId;
560
555
  [_gIdDelegate updateGroupIdentifier];
561
- // [self setupLayout];
562
556
  }
563
557
 
564
- - (void)subviewRecycle: (UIView *)subview {
558
+ - (void)didAddSubview:(UIView *)subview {
559
+ [super didAddSubview: subview];
560
+ [_gIdDelegate updateGroupIdentifier];
561
+ }
562
+
563
+ - (void)willRemoveSubview:(UIView *)subview {
565
564
  [_gIdDelegate clearSubview: subview];
566
565
  if (@available(iOS 15.0, *)) {
567
566
  subview.focusEffect = nil;
568
567
  }
569
- }
570
-
571
- - (void)willRemoveSubview:(UIView *)subview {
568
+
572
569
  [super willRemoveSubview:subview];
573
- [self subviewRecycle: subview];
574
570
  }
575
571
 
576
572
  - (void)viewControllerChanged:(NSNotification *)notification {
@@ -589,7 +585,7 @@ API_AVAILABLE(ios(13.0)) {
589
585
  [self onContextMenuPressHandler];
590
586
  [self onBubbledContextMenuPressHandler];
591
587
  }
592
-
588
+
593
589
  return nil;
594
590
  }
595
591
 
@@ -15,6 +15,7 @@
15
15
 
16
16
  #ifdef RCT_NEW_ARCH_ENABLED
17
17
  #include <string>
18
+ #import "RCTViewComponentView+RNCEKVExternalKeyboard.h"
18
19
  #import <react/renderer/components/RNExternalKeyboardViewSpec/ComponentDescriptors.h>
19
20
  #import <react/renderer/components/RNExternalKeyboardViewSpec/EventEmitters.h>
20
21
  #import <react/renderer/components/RNExternalKeyboardViewSpec/Props.h>
@@ -32,31 +33,24 @@ using namespace facebook::react;
32
33
 
33
34
  #endif
34
35
 
35
- @implementation RNCEKVKeyboardFocusGroup {
36
- UIView* _entry;
37
- UIView* _exit;
38
- UIView* _lock;
39
- }
36
+ @implementation RNCEKVKeyboardFocusGroup
40
37
 
41
38
  - (instancetype)initWithFrame:(CGRect)frame
42
39
  {
43
40
  if (self = [super initWithFrame:frame]) {
44
41
  _isGroupFocused = false;
45
- _entry = nil;
46
- _exit = nil;
47
42
  #ifdef RCT_NEW_ARCH_ENABLED
48
43
  static const auto defaultProps = std::make_shared<const KeyboardFocusGroupProps>();
49
44
  _props = defaultProps;
50
45
  #endif
51
46
  }
52
-
47
+
53
48
  return self;
54
49
  }
55
50
 
56
-
57
51
  - (void)didUpdateFocusInContext:(UIFocusUpdateContext *)context
58
52
  withAnimationCoordinator:(UIFocusAnimationCoordinator *)coordinator {
59
-
53
+
60
54
  [super didUpdateFocusInContext:context withAnimationCoordinator:coordinator];
61
55
  NSString* nextFocusGroup = context.nextFocusedView.focusGroupIdentifier;
62
56
  BOOL isFocused = [nextFocusGroup isEqual: _customGroupId];
@@ -66,16 +60,6 @@ using namespace facebook::react;
66
60
  }
67
61
  }
68
62
 
69
- - (void)layoutSubviews {
70
- [super layoutSubviews];
71
-
72
- if (@available(iOS 14.0, *)) {
73
- if(_customGroupId) {
74
- self.focusGroupIdentifier = _customGroupId;
75
- }
76
- }
77
- }
78
-
79
63
  #ifdef RCT_NEW_ARCH_ENABLED
80
64
 
81
65
  - (void)onFocusChangeHandler:(BOOL) isFocused {
@@ -96,146 +80,22 @@ using namespace facebook::react;
96
80
  }
97
81
  #endif
98
82
 
99
-
100
- #pragma mark - Get Order Focus List
101
- - (NSArray<UIView *> *)getOrder {
102
- RNCEKVRelashioship* orderRelationship = [[RNCEKVOrderLinking sharedInstance] getInfo:_orderGroup];
103
- return [orderRelationship getArray];
104
- }
105
-
106
-
107
- #pragma mark - Focus Find Index
108
- - (int)findOrderIndex:(NSArray *)order element:(UIView*)el {
109
- int resultIndex = -1;
110
-
111
- for (int i = 0; i < order.count; i++) {
112
- UIView *element = order[i];
113
- if (element.subviews[0] == el) { //ToDo focus element
114
- resultIndex = i;
115
- break;
116
- }
117
- }
118
-
119
- return resultIndex;
120
- }
121
-
122
-
123
- #pragma mark - Next Focus Handling
124
- - (void)handleNextFocus:(UIView *)current currentIndex:(NSInteger)currentIndex {
125
- NSArray<UIView *> * order = [self getOrder];
126
-
127
- BOOL isEntry = _entry == current;
128
- if (isEntry) {
129
- UIView* firstElement = order[0];
130
- if ([firstElement isKindOfClass:[RNCEKVExternalKeyboardView class]]) {
131
- [(RNCEKVExternalKeyboardView*)firstElement focus];
132
- }
133
- }
134
-
135
- BOOL isLast = currentIndex == order.count - 1 && _exit;
136
- if (isLast) {
137
- [self updateFocus: _exit];
138
- }
139
-
140
- BOOL inOrderRange = currentIndex >= 0 && currentIndex < order.count - 1;
141
- if (inOrderRange) {
142
- UIView* nextElement = order[currentIndex + 1];
143
- if ([nextElement isKindOfClass:[RNCEKVExternalKeyboardView class]]) {
144
- [(RNCEKVExternalKeyboardView*)nextElement focus];
145
- }
146
- }
147
- }
148
-
149
- #pragma mark - Prev Focus Handling
150
- - (void)handlePrevFocus:(UIView *)current currentIndex:(NSInteger)currentIndex {
151
- NSArray<UIView *> * order = [self getOrder];
152
-
153
- BOOL isExit = _exit == current;
154
- if (isExit) {
155
- UIView* lastElement = order[order.count - 1];
156
- if ([lastElement isKindOfClass:[RNCEKVExternalKeyboardView class]]) {
157
- [(RNCEKVExternalKeyboardView*)lastElement focus];
158
- }
159
- }
160
-
161
- BOOL isFirst = currentIndex == 0 && _entry;
162
- if (isFirst) {
163
- [self updateFocus: _entry];
164
- }
165
-
166
- BOOL inRange = currentIndex > 0 && currentIndex <= order.count - 1;
167
- if (inRange) {
168
- UIView* prevElement = order[currentIndex - 1];
169
- if ([prevElement isKindOfClass:[RNCEKVExternalKeyboardView class]]) {
170
- [(RNCEKVExternalKeyboardView*)prevElement focus];
83
+ - (void )setCustomGroupId: (NSString *) customGroupId {
84
+ if (@available(iOS 14.0, *)) {
85
+ _customGroupId = customGroupId;
86
+ [self updateFocusGroup: customGroupId];
171
87
  }
172
- }
173
88
  }
174
89
 
175
- #pragma mark - Focus Order Handler
176
- - (BOOL)shouldUpdateFocusInContext:(UIFocusUpdateContext *)context {
177
- return YES;
178
- UIView *next = (UIView *)context.nextFocusedItem;
179
- UIView *current = (UIView *)context.previouslyFocusedItem;
180
- UIFocusHeading movementHint = context.focusHeading;
181
-
182
- // UIView* rnkv = current.superview; //ToDo Create a map for RNKV <-> Target relations
183
- // if ([rnkv isKindOfClass:[RNCEKVExternalKeyboardView class]]) {
184
- // NSUInteger rawFocusLockValue = [((RNCEKVExternalKeyboardView *)rnkv).lockFocus unsignedIntegerValue];
185
- //
186
- // BOOL isDirectionLock = (rawFocusLockValue & movementHint) != 0;
187
- // if (isDirectionLock) {
188
- // return NO;
189
- // }
190
- // }
191
-
192
- if(_orderGroup) {
193
- RNCEKVRelashioship* orderRelationship = [[RNCEKVOrderLinking sharedInstance] getInfo:_orderGroup];
194
- NSArray *order = [orderRelationship getArray];
195
- if(order.count == 0) {
196
- return YES;
197
- }
198
-
199
- int currentIndex = [self findOrderIndex:order element:current];
200
- int nextIndex = [self findOrderIndex:order element:next];
201
90
 
202
- BOOL isEntryElement = _entry == nil && currentIndex == -1 && movementHint == UIFocusHeadingNext;
203
- if(isEntryElement) {
204
- _entry = current;
205
- }
206
-
207
- BOOL isExit = _exit == nil && nextIndex == -1 && movementHint == UIFocusHeadingNext;
208
- if(isExit) {
209
- _exit = next;
210
- }
211
-
212
- if(context.focusHeading == UIFocusHeadingNext) {
213
- [self handleNextFocus:current currentIndex: currentIndex];
214
- return YES;
215
- }
216
-
217
-
218
- if(context.focusHeading == UIFocusHeadingPrevious) {
219
- [self handlePrevFocus:current currentIndex: currentIndex];
220
- return YES;
91
+ - (void )updateFocusGroup: (NSString *) customGroupId {
92
+ if (@available(iOS 14.0, *)) {
93
+ #ifdef RCT_NEW_ARCH_ENABLED
94
+ self.rncekvCustomGroup = _customGroupId;
95
+ #else
96
+ self.focusGroupIdentifier = _customGroupId;
97
+ #endif
221
98
  }
222
-
223
- //ToDo add sides focus handlers
224
- }
225
-
226
- return YES;
227
- }
228
-
229
- - (void)updateFocus:(UIView *)focusingView {
230
- UIViewController *controller = self.reactViewController;
231
-
232
- if (controller != nil) {
233
- controller.customFocusView = focusingView;
234
- dispatch_async(dispatch_get_main_queue(), ^{
235
- [controller setNeedsFocusUpdate];
236
- [controller updateFocusIfNeeded];
237
- });
238
- }
239
99
  }
240
100
 
241
101
 
@@ -250,8 +110,9 @@ using namespace facebook::react;
250
110
  - (void)prepareForRecycle
251
111
  {
252
112
  [super prepareForRecycle];
253
- _customGroupId = nil;
254
113
  self.tintColor = nil;
114
+ [self updateFocusGroup: nil];
115
+ _customGroupId = nil;
255
116
  }
256
117
 
257
118
  - (void)updateProps:(Props::Shared const &)props oldProps:(Props::Shared const &)oldProps
@@ -260,8 +121,8 @@ using namespace facebook::react;
260
121
  const auto &newViewProps = *std::static_pointer_cast<KeyboardFocusGroupProps const>(props);
261
122
  [super updateProps
262
123
  :props oldProps:oldProps];
263
-
264
-
124
+
125
+
265
126
  UIColor* newColor = RCTUIColorFromSharedColor(newViewProps.tintColor);
266
127
  BOOL isDifferentColor = ![newColor isEqual: self.tintColor];
267
128
  BOOL renewColor = newColor != nil && self.tintColor == nil;
@@ -269,8 +130,8 @@ using namespace facebook::react;
269
130
  if(isColorChanged || renewColor || isDifferentColor) {
270
131
  self.tintColor = newColor;
271
132
  }
272
-
273
- if(oldViewProps.groupIdentifier != newViewProps.groupIdentifier || !self.customGroupId) {
133
+
134
+ if(oldViewProps.groupIdentifier != newViewProps.groupIdentifier || !self.customGroupId) {
274
135
  if(newViewProps.groupIdentifier.empty()) {
275
136
  [self setCustomGroupId:nil];
276
137
  } else {
@@ -278,11 +139,6 @@ using namespace facebook::react;
278
139
  [self setCustomGroupId:newGroupId];
279
140
  }
280
141
  }
281
-
282
- if(oldViewProps.orderGroup != newViewProps.orderGroup) {
283
- _orderGroup = [NSString stringWithUTF8String:newViewProps.orderGroup.c_str()];
284
- }
285
-
286
142
  }
287
143
 
288
144
  Class<RCTComponentViewProtocol> KeyboardFocusGroupCls(void)
@@ -296,7 +152,3 @@ Class<RCTComponentViewProtocol> KeyboardFocusGroupCls(void)
296
152
 
297
153
 
298
154
  @end
299
-
300
-
301
-
302
-
@@ -5,7 +5,6 @@
5
5
  #import <React/RCTUITextView.h>
6
6
  #import "RNCEKVFocusEffectUtility.h"
7
7
  #import "RCTBaseTextInputView.h"
8
- #import "RNCEKVGroupIdentifierDelegate.h"
9
8
 
10
9
  #ifdef RCT_NEW_ARCH_ENABLED
11
10
  #import "RCTTextInputComponentView+RNCEKVExternalKeyboard.h"
@@ -38,9 +37,7 @@ using namespace facebook::react;
38
37
  static const NSInteger AUTO_FOCUS = 2;
39
38
  static const NSInteger AUTO_BLUR = 2;
40
39
 
41
- @implementation RNCEKVTextInputFocusWrapper{
42
- RNCEKVGroupIdentifierDelegate* _gIdDelegate;
43
- }
40
+ @implementation RNCEKVTextInputFocusWrapper
44
41
 
45
42
 
46
43
  - (instancetype)initWithFrame:(CGRect)frame
@@ -50,9 +47,8 @@ static const NSInteger AUTO_BLUR = 2;
50
47
  static const auto defaultProps = std::make_shared<const TextInputFocusWrapperProps>();
51
48
  _props = defaultProps;
52
49
  #endif
53
- _gIdDelegate = [[RNCEKVGroupIdentifierDelegate alloc] initWithView:self];
54
50
  }
55
-
51
+
56
52
  return self;
57
53
  }
58
54
 
@@ -76,36 +72,29 @@ static const NSInteger AUTO_BLUR = 2;
76
72
  [self cleanReferences];
77
73
  }
78
74
 
79
- - (void)willRemoveSubview:(UIView *)subview {
80
- [super willRemoveSubview:subview];
81
- if(_customGroupId && _gIdDelegate) {
82
- [_gIdDelegate clear];
83
- }
84
- }
85
-
86
75
  - (void)updateProps:(Props::Shared const &)props oldProps:(Props::Shared const &)oldProps
87
76
  {
88
77
  const auto &oldViewProps = *std::static_pointer_cast<TextInputFocusWrapperProps const>(_props);
89
78
  const auto &newViewProps = *std::static_pointer_cast<TextInputFocusWrapperProps const>(props);
90
79
  [super updateProps
91
80
  :props oldProps:oldProps];
92
-
81
+
93
82
  if(oldViewProps.canBeFocused != newViewProps.canBeFocused) {
94
83
  [self setCanBeFocused: newViewProps.canBeFocused];
95
84
  }
96
-
85
+
97
86
  if(oldViewProps.focusType != newViewProps.focusType) {
98
87
  [self setFocusType: newViewProps.focusType];
99
88
  }
100
-
89
+
101
90
  if(oldViewProps.blurType != newViewProps.blurType) {
102
91
  [self setBlurType: newViewProps.blurType];
103
92
  }
104
-
93
+
105
94
  if(oldViewProps.blurOnSubmit != newViewProps.blurOnSubmit) {
106
95
  [self setBlurOnSubmit: newViewProps.blurOnSubmit];
107
96
  }
108
-
97
+
109
98
  if(oldViewProps.multiline != newViewProps.multiline) {
110
99
  [self setMultiline: newViewProps.multiline];
111
100
  }
@@ -116,26 +105,14 @@ static const NSInteger AUTO_BLUR = 2;
116
105
  [self setIsHaloActive: @(haloState)];
117
106
  }
118
107
  }
119
-
120
-
108
+
109
+
121
110
  UIColor* newColor = RCTUIColorFromSharedColor(newViewProps.tintColor);
122
111
  BOOL renewColor = newColor != nil && self.tintColor == nil;
123
112
  BOOL isColorChanged = oldViewProps.tintColor != newViewProps.tintColor;
124
113
  if(isColorChanged || renewColor) {
125
114
  self.tintColor = RCTUIColorFromSharedColor(newViewProps.tintColor);
126
115
  }
127
-
128
- BOOL isNewGroup = oldViewProps.groupIdentifier != newViewProps.groupIdentifier;
129
- BOOL recoverCustomGroup = !self.customGroupId && !newViewProps.groupIdentifier.empty();
130
- if(isNewGroup || recoverCustomGroup) {
131
- if(newViewProps.groupIdentifier.empty() && self.customGroupId != nil) {
132
- self.customGroupId = nil;
133
- }
134
- if(!newViewProps.groupIdentifier.empty()) {
135
- NSString *newGroupId = [NSString stringWithUTF8String:newViewProps.groupIdentifier.c_str()];
136
- [self setCustomGroupId:newGroupId];
137
- }
138
- }
139
116
  }
140
117
 
141
118
  Class<RCTComponentViewProtocol> TextInputFocusWrapperCls(void)
@@ -194,11 +171,11 @@ Class<RCTComponentViewProtocol> TextInputFocusWrapperCls(void)
194
171
 
195
172
  - (void)didUpdateFocusInContext:(UIFocusUpdateContext *)context
196
173
  withAnimationCoordinator:(UIFocusAnimationCoordinator *)coordinator {
197
-
174
+
198
175
  if(_textField == nil) {
199
176
  _textField = [self getTextFieldComponent];
200
177
  }
201
-
178
+
202
179
  BOOL isNext = context.nextFocusedView == _textField;
203
180
  BOOL isPrev = context.previouslyFocusedView == _textField;
204
181
 
@@ -210,7 +187,7 @@ Class<RCTComponentViewProtocol> TextInputFocusWrapperCls(void)
210
187
  }
211
188
  }
212
189
  }
213
-
190
+
214
191
  if(isPrev) {
215
192
  [self onFocusChange: NO];
216
193
  if(self.blurType == AUTO_BLUR) {
@@ -225,7 +202,7 @@ Class<RCTComponentViewProtocol> TextInputFocusWrapperCls(void)
225
202
  @try{
226
203
  UIView* input = self.subviews[0];
227
204
  UIView* backedTextInputView = nil;
228
-
205
+
229
206
  #ifdef RCT_NEW_ARCH_ENABLED
230
207
  if([input isKindOfClass: [RCTTextInputComponentView class]]) {
231
208
  backedTextInputView = ((RCTTextInputComponentView *)input).backedTextInputView;
@@ -237,7 +214,7 @@ Class<RCTComponentViewProtocol> TextInputFocusWrapperCls(void)
237
214
  backedTextInputView = ((RCTSinglelineTextInputView *)input).backedTextInputView;
238
215
  }
239
216
  #endif
240
-
217
+
241
218
  return backedTextInputView;
242
219
  } @catch (NSException *ex) {
243
220
  return nil;
@@ -282,7 +259,7 @@ Class<RCTComponentViewProtocol> TextInputFocusWrapperCls(void)
282
259
  if(self.subviews.count == 0) {
283
260
  return;
284
261
  }
285
-
262
+
286
263
  UIView* view = self.subviews[0];
287
264
  if (@available(iOS 15.0, *)) {
288
265
  BOOL isTextInput = [self getIsTextInputView: view];
@@ -298,16 +275,16 @@ Class<RCTComponentViewProtocol> TextInputFocusWrapperCls(void)
298
275
  if (@available(iOS 13.4, *)) {
299
276
  UIKey *key = presses.allObjects[0].key;
300
277
  BOOL isEnter = [key.characters isEqualToString:@"\n"] || [key.characters isEqualToString:@"\r"];
301
-
278
+
302
279
  RCTUITextField* textView = _textField != nil ? _textField : [self getTextFieldComponent];
303
280
  if(isEnter && textView && !textView.isFirstResponder) {
304
281
  [_textField reactFocus];
305
282
  return;
306
283
  }
307
-
284
+
308
285
  if(self.multiline) {
309
286
  BOOL isShiftPressed = (key.modifierFlags & UIKeyModifierShift) != 0;
310
-
287
+
311
288
  if(textView && textView.isFirstResponder) {
312
289
  if(!isShiftPressed && isEnter) {
313
290
  [self onMultiplyTextSubmitHandler: (UIView*)textView];
@@ -318,7 +295,7 @@ Class<RCTComponentViewProtocol> TextInputFocusWrapperCls(void)
318
295
  }
319
296
  }
320
297
  }
321
-
298
+
322
299
  [super pressesBegan:presses withEvent:event];
323
300
  }
324
301
 
@@ -335,20 +312,13 @@ Class<RCTComponentViewProtocol> TextInputFocusWrapperCls(void)
335
312
  UIView* focusingView = self.subviews[0].subviews[0];
336
313
  return focusingView;
337
314
  }
338
-
339
- return nil;
340
- }
341
315
 
342
- - (void)layoutSubviews {
343
- [super layoutSubviews];
344
- // ToDo RNCEKV-7 add cache for halo update
345
- [_gIdDelegate updateGroupIdentifier];
316
+ return nil;
346
317
  }
347
318
 
348
-
349
319
  - (void)willMoveToSuperview:(UIView *)newSuperview {
350
320
  [super willMoveToSuperview:newSuperview];
351
-
321
+
352
322
  if (newSuperview == nil) {
353
323
  [self cleanReferences];
354
324
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "react-native-external-keyboard",
3
- "version": "0.6.2",
3
+ "version": "0.6.3",
4
4
  "description": "Toolkit for improving physical keyboard support in React Native",
5
5
  "main": "lib/commonjs/index",
6
6
  "module": "lib/module/index",