diff --git a/React/Views/SafeAreaView/RCTSafeAreaView.m b/React/Views/SafeAreaView/RCTSafeAreaView.m index e4fe4b6d171..593210d75ca 100644 --- a/React/Views/SafeAreaView/RCTSafeAreaView.m +++ b/React/Views/SafeAreaView/RCTSafeAreaView.m @@ -29,8 +29,6 @@ RCT_NOT_IMPLEMENTED(- (instancetype)initWithCoder:(NSCoder *)decoder) RCT_NOT_IMPLEMENTED(- (instancetype)initWithFrame:(CGRect)frame) -#if defined(__IPHONE_OS_VERSION_MAX_ALLOWED) && __IPHONE_OS_VERSION_MAX_ALLOWED >= 110000 /* __IPHONE_11_0 */ - static BOOL UIEdgeInsetsEqualToEdgeInsetsWithThreshold(UIEdgeInsets insets1, UIEdgeInsets insets2, CGFloat threshold) { return ABS(insets1.left - insets2.left) <= threshold && @@ -39,25 +37,57 @@ static BOOL UIEdgeInsetsEqualToEdgeInsetsWithThreshold(UIEdgeInsets insets1, UIE ABS(insets1.bottom - insets2.bottom) <= threshold; } +#if defined(__IPHONE_OS_VERSION_MAX_ALLOWED) && __IPHONE_OS_VERSION_MAX_ALLOWED >= 110000 /* __IPHONE_11_0 */ + - (void)safeAreaInsetsDidChange { if (![self respondsToSelector:@selector(safeAreaInsets)]) { return; } - UIEdgeInsets safeAreaInsets = self.safeAreaInsets; + [self setSafeAreaInsets:self.safeAreaInsets]; +} +#endif + +// Emulate safe area for iOS < 11 +- (void)layoutSubviews +{ + [super layoutSubviews]; + if ([self respondsToSelector:@selector(safeAreaInsets)]) { + return; + } + UIViewController* vc = self.reactViewController; + if (!vc) { + return; + } + CGFloat topLayoutOffset = vc.topLayoutGuide.length; + CGFloat bottomLayoutOffset = vc.bottomLayoutGuide.length; + CGRect safeArea = vc.view.bounds; + safeArea.origin.y += topLayoutOffset; + safeArea.size.height -= topLayoutOffset + bottomLayoutOffset; + CGRect localSafeArea = [vc.view convertRect:safeArea toView:self]; + UIEdgeInsets safeAreaInsets = UIEdgeInsetsMake(0, 0, 0, 0); + if (CGRectGetMinY(localSafeArea) > CGRectGetMinY(self.bounds)) { + safeAreaInsets.top = CGRectGetMinY(localSafeArea) - CGRectGetMinY(self.bounds); + } + if (CGRectGetMaxY(localSafeArea) < CGRectGetMaxY(self.bounds)) { + safeAreaInsets.bottom = CGRectGetMaxY(self.bounds) - CGRectGetMaxY(localSafeArea); + } + + [self setSafeAreaInsets:safeAreaInsets]; +} + +- (void)setSafeAreaInsets:(UIEdgeInsets)safeAreaInsets +{ if (UIEdgeInsetsEqualToEdgeInsetsWithThreshold(safeAreaInsets, _currentSafeAreaInsets, 1.0 / RCTScreenScale())) { return; } _currentSafeAreaInsets = safeAreaInsets; - RCTSafeAreaViewLocalData *localData = - [[RCTSafeAreaViewLocalData alloc] initWithInsets:safeAreaInsets]; + RCTSafeAreaViewLocalData *localData = [[RCTSafeAreaViewLocalData alloc] initWithInsets:safeAreaInsets]; [_bridge.uiManager setLocalData:localData forView:self]; } -#endif - @end