1#import "RNCSafeAreaProvider.h" 2 3#import <React/RCTBridge.h> 4#import <React/RCTUIManager.h> 5#import "RNCSafeAreaUtils.h" 6 7@implementation RNCSafeAreaProvider { 8 UIEdgeInsets _currentSafeAreaInsets; 9 CGRect _currentFrame; 10 BOOL _initialInsetsSent; 11} 12 13- (void)safeAreaInsetsDidChange 14{ 15 [self invalidateSafeAreaInsets]; 16} 17 18- (void)invalidateSafeAreaInsets 19{ 20 // This gets called before the view size is set by react-native so 21 // make sure to wait so we don't set wrong insets to JS. 22 if (CGSizeEqualToSize(self.frame.size, CGSizeZero)) { 23 return; 24 } 25 26 UIEdgeInsets safeAreaInsets = self.safeAreaInsets; 27 CGRect frame = [self convertRect:self.bounds toView:nil]; 28 29 if (_initialInsetsSent && 30 UIEdgeInsetsEqualToEdgeInsetsWithThreshold(safeAreaInsets, _currentSafeAreaInsets, 1.0 / RCTScreenScale()) && 31 CGRectEqualToRect(frame, _currentFrame)) { 32 return; 33 } 34 35 _initialInsetsSent = YES; 36 _currentSafeAreaInsets = safeAreaInsets; 37 _currentFrame = frame; 38 39 [NSNotificationCenter.defaultCenter postNotificationName:RNCSafeAreaDidChange object:self userInfo:nil]; 40 41 self.onInsetsChange(@{ 42 @"insets" : @{ 43 @"top" : @(safeAreaInsets.top), 44 @"right" : @(safeAreaInsets.right), 45 @"bottom" : @(safeAreaInsets.bottom), 46 @"left" : @(safeAreaInsets.left), 47 }, 48 @"frame" : @{ 49 @"x" : @(frame.origin.x), 50 @"y" : @(frame.origin.y), 51 @"width" : @(frame.size.width), 52 @"height" : @(frame.size.height), 53 }, 54 }); 55} 56 57- (void)layoutSubviews 58{ 59 [super layoutSubviews]; 60 61 [self invalidateSafeAreaInsets]; 62} 63 64@end 65