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