11#import " RNCSafeAreaProvider.h"
22
3+ #import < React/RCTEventDispatcher.h>
34#import < React/RCTBridge.h>
45#import < React/RCTUIManager.h>
6+ #import " RCTUIManagerObserverCoordinator.h"
57#import " RNCSafeAreaUtils.h"
8+ #import " RNCChangeEvent.h"
9+
10+ @interface RNCSafeAreaProvider () <RCTUIManagerObserver>
11+
12+ @end
613
714@implementation RNCSafeAreaProvider {
15+ id <RCTEventDispatcherProtocol> _eventDispatcher;
816 UIEdgeInsets _currentSafeAreaInsets;
917 CGRect _currentFrame;
1018 BOOL _initialInsetsSent;
19+ uint16_t _coalescingKey;
1120}
1221
13- - (instancetype )init
22+ - (instancetype )initWithEventDispatcher : ( id <RCTEventDispatcherProtocol>) eventDispatcher
1423{
15- if ((self = [super init ])) {
16- #if !TARGET_OS_TV && !TARGET_OS_OSX
24+ RCTAssertParam (eventDispatcher);
25+
26+ if ((self = [super initWithFrame: CGRectZero])) {
27+ #if !TARGET_OS_TV
28+
29+ _eventDispatcher = eventDispatcher;
30+
1731 [NSNotificationCenter .defaultCenter addObserver: self
1832 selector: @selector (invalidateSafeAreaInsets )
1933 name: UIKeyboardDidShowNotification
@@ -48,48 +62,31 @@ - (void)invalidateSafeAreaInsets
4862 return ;
4963 }
5064
51- #if TARGET_OS_IPHONE
5265 UIEdgeInsets safeAreaInsets = self.safeAreaInsets ;
53- #elif TARGET_OS_OSX
54- NSEdgeInsets safeAreaInsets;
55- if (@available (macOS 11.0 , *)) {
56- safeAreaInsets = self.safeAreaInsets ;
57- } else {
58- safeAreaInsets = NSEdgeInsetsZero ;
59- }
60- #endif
6166 CGRect frame = [self convertRect: self .bounds toView: RNCParentViewController (self ).view];
6267
6368 if (_initialInsetsSent &&
64- #if TARGET_OS_IPHONE
6569 UIEdgeInsetsEqualToEdgeInsetsWithThreshold (safeAreaInsets, _currentSafeAreaInsets, 1.0 / RCTScreenScale ()) &&
66- #elif TARGET_OS_OSX
67- NSEdgeInsetsEqualToEdgeInsetsWithThreshold (safeAreaInsets, _currentSafeAreaInsets, 1.0 / RCTScreenScale()) &&
68- #endif
6970 CGRectEqualToRect (frame, _currentFrame)) {
7071 return ;
7172 }
72-
73+
7374 _initialInsetsSent = YES ;
7475 _currentSafeAreaInsets = safeAreaInsets;
7576 _currentFrame = frame;
7677
7778 [NSNotificationCenter .defaultCenter postNotificationName: RNCSafeAreaDidChange object: self userInfo: nil ];
7879
79- self.onInsetsChange (@{
80- @" insets" : @{
81- @" top" : @(safeAreaInsets.top ),
82- @" right" : @(safeAreaInsets.right ),
83- @" bottom" : @(safeAreaInsets.bottom ),
84- @" left" : @(safeAreaInsets.left ),
85- },
86- @" frame" : @{
87- @" x" : @(frame.origin .x ),
88- @" y" : @(frame.origin .y ),
89- @" width" : @(frame.size .width ),
90- @" height" : @(frame.size .height ),
91- },
92- });
80+ // There's currently only 1 event name "change", so the _coalescingKey doesn't needs to be incremented
81+ // Increment _coalescingKey if safeAreaInsets and frame are sent as separate events
82+ RNCChangeEvent *changeEvent = [[RNCChangeEvent alloc ] initWithEventName: @" onInsetsChange"
83+ reactTag: self .reactTag
84+ insets: safeAreaInsets
85+ frame: frame
86+ coalescingKey: _coalescingKey];
87+
88+
89+ [_eventDispatcher sendEvent: changeEvent];
9390}
9491
9592- (void )layoutSubviews
@@ -99,4 +96,13 @@ - (void)layoutSubviews
9996 [self invalidateSafeAreaInsets ];
10097}
10198
99+ - (void )dealloc
100+ {
101+ [_eventDispatcher.bridge.uiManager.observerCoordinator removeObserver: self ];
102+ }
103+
104+
105+ RCT_NOT_IMPLEMENTED (-(instancetype )initWithFrame : (CGRect)frame)
106+ RCT_NOT_IMPLEMENTED(-(instancetype )initWithCoder : (NSCoder *)aDecoder)
107+
102108@end
0 commit comments