Skip to content

Commit

Permalink
Remove iOS 11 deprecation warnings around SafeArea (#32851)
Browse files Browse the repository at this point in the history
Summary:
We don't have to check or emulate the safe area for iOS 11 above. I deleted the unnecessary check for the safe area.

This is a continuation pull request of these iOS 11 availability check.
* [Remove iOS 11 version check by ken0nek · Pull Request #32151 · facebook/react-native](#32151)
* [Remove iOS 11 availability check by ken0nek · Pull Request #32488 · facebook/react-native](#32488)

-----

- Stop using layout guide (`topLayoutGuide`, `bottomLayoutGuide`)
- Refactor `RCTSafeAreaView`
- Delete `emulateUnlessSupported` property

Docs PR: facebook/react-native-website#2919

## Changelog

<!-- Help reviewers and the release process by writing your own changelog entry. For an example, see:
https://github.com/facebook/react-native/wiki/Changelog
-->

[iOS] [Removed] - Remove `emulateUnlessSupported`

Pull Request resolved: #32851

Reviewed By: philIip, sammy-SC

Differential Revision: D33586023

Pulled By: cortinico

fbshipit-source-id: 75fc1037141f71d9340c7b875a6bf86f9cfd6a02
  • Loading branch information
ken0nek authored and facebook-github-bot committed May 16, 2022
1 parent c274456 commit c73e021
Show file tree
Hide file tree
Showing 9 changed files with 23 additions and 157 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -9,16 +9,14 @@
*/

import type {ViewProps} from '../View/ViewPropTypes';
import type {WithDefault} from '../../Types/CodegenTypes';

import codegenNativeComponent from '../../Utilities/codegenNativeComponent';
import type {HostComponent} from '../../Renderer/shims/ReactNativeTypes';

type NativeProps = $ReadOnly<{|
...ViewProps,

// Props
emulateUnlessSupported?: WithDefault<boolean, false>,
// No props
|}>;

export default (codegenNativeComponent<NativeProps>('SafeAreaView', {
Expand Down
33 changes: 3 additions & 30 deletions Libraries/Components/SafeAreaView/SafeAreaView.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,18 +12,9 @@ import Platform from '../../Utilities/Platform';
import * as React from 'react';
import View from '../View/View';

import type {HostComponent} from '../../Renderer/shims/ReactNativeTypes';
import type {ViewProps} from '../View/ViewPropTypes';

type Props = $ReadOnly<{|
...ViewProps,
emulateUnlessSupported?: boolean,
|}>;

let exported: React.AbstractComponent<
Props,
React.ElementRef<HostComponent<mixed>>,
>;
let exported: React.AbstractComponent<ViewProps, React.ElementRef<typeof View>>;

/**
* Renders nested content and automatically applies paddings reflect the portion
Expand All @@ -35,27 +26,9 @@ let exported: React.AbstractComponent<
* sensor housing area on iPhone X).
*/
if (Platform.OS === 'android') {
exported = React.forwardRef<Props, React.ElementRef<HostComponent<mixed>>>(
function SafeAreaView(props, forwardedRef) {
const {emulateUnlessSupported, ...localProps} = props;
return <View {...localProps} ref={forwardedRef} />;
},
);
exported = View;
} else {
const RCTSafeAreaViewNativeComponent =
require('./RCTSafeAreaViewNativeComponent').default;

exported = React.forwardRef<Props, React.ElementRef<HostComponent<mixed>>>(
function SafeAreaView(props, forwardedRef) {
return (
<RCTSafeAreaViewNativeComponent
emulateUnlessSupported={true}
{...props}
ref={forwardedRef}
/>
);
},
);
exported = require('./RCTSafeAreaViewNativeComponent').default;
}

export default exported;
Original file line number Diff line number Diff line change
@@ -1,9 +1,7 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`<SafeAreaView /> should render as expected: should deep render when mocked (please verify output manually) 1`] = `
<RCTSafeAreaView
emulateUnlessSupported={true}
>
<RCTSafeAreaView>
<View>
<Text>
Hello World!
Expand All @@ -13,9 +11,7 @@ exports[`<SafeAreaView /> should render as expected: should deep render when moc
`;

exports[`<SafeAreaView /> should render as expected: should deep render when not mocked (please verify output manually) 1`] = `
<RCTSafeAreaView
emulateUnlessSupported={true}
>
<RCTSafeAreaView>
<View>
<Text>
Hello World!
Expand All @@ -25,21 +21,21 @@ exports[`<SafeAreaView /> should render as expected: should deep render when not
`;

exports[`<SafeAreaView /> should render as expected: should shallow render as <SafeAreaView /> when mocked 1`] = `
<ForwardRef(SafeAreaView)>
<RCTSafeAreaView>
<View>
<Text>
Hello World!
</Text>
</View>
</ForwardRef(SafeAreaView)>
</RCTSafeAreaView>
`;

exports[`<SafeAreaView /> should render as expected: should shallow render as <SafeAreaView /> when not mocked 1`] = `
<ForwardRef(SafeAreaView)>
<RCTSafeAreaView>
<View>
<Text>
Hello World!
</Text>
</View>
</ForwardRef(SafeAreaView)>
</RCTSafeAreaView>
`;
Original file line number Diff line number Diff line change
Expand Up @@ -30,15 +30,6 @@ - (instancetype)initWithFrame:(CGRect)frame
return self;
}

- (UIEdgeInsets)_safeAreaInsets
{
if (@available(iOS 11.0, *)) {
return self.safeAreaInsets;
}

return UIEdgeInsetsZero;
}

- (void)safeAreaInsetsDidChange
{
[super safeAreaInsetsDidChange];
Expand All @@ -52,7 +43,7 @@ - (void)_updateStateIfNecessary
return;
}

UIEdgeInsets insets = [self _safeAreaInsets];
UIEdgeInsets insets = self.safeAreaInsets;
insets.left = RCTRoundPixelValue(insets.left);
insets.top = RCTRoundPixelValue(insets.top);
insets.right = RCTRoundPixelValue(insets.right);
Expand Down
19 changes: 9 additions & 10 deletions React/Views/RCTWrapperViewController.m
Original file line number Diff line number Diff line change
Expand Up @@ -16,11 +16,11 @@
@implementation RCTWrapperViewController {
UIView *_wrapperView;
UIView *_contentView;
CGFloat _previousTopLayoutLength;
CGFloat _previousBottomLayoutLength;
CGFloat _previousTopInset;
CGFloat _previousBottomInset;

id<UILayoutSupport> _currentTopLayoutGuide;
id<UILayoutSupport> _currentBottomLayoutGuide;
CGFloat _currentTopInset;
CGFloat _currentBottomInset;
}

- (instancetype)initWithContentView:(UIView *)contentView
Expand All @@ -41,8 +41,8 @@ - (void)viewWillLayoutSubviews
{
[super viewWillLayoutSubviews];

_currentTopLayoutGuide = self.topLayoutGuide;
_currentBottomLayoutGuide = self.bottomLayoutGuide;
_currentTopInset = self.view.safeAreaInsets.top;
_currentBottomInset = self.view.safeAreaInsets.bottom;
}

static BOOL RCTFindScrollViewAndRefreshContentInsetInView(UIView *view)
Expand All @@ -63,11 +63,10 @@ - (void)viewDidLayoutSubviews
{
[super viewDidLayoutSubviews];

if (_previousTopLayoutLength != _currentTopLayoutGuide.length ||
_previousBottomLayoutLength != _currentBottomLayoutGuide.length) {
if (_previousTopInset != _currentTopInset || _previousBottomInset != _currentBottomInset) {
RCTFindScrollViewAndRefreshContentInsetInView(_contentView);
_previousTopLayoutLength = _currentTopLayoutGuide.length;
_previousBottomLayoutLength = _currentBottomLayoutGuide.length;
_previousTopInset = _currentTopInset;
_previousBottomInset = _currentBottomInset;
}
}

Expand Down
2 changes: 0 additions & 2 deletions React/Views/SafeAreaView/RCTSafeAreaView.h
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,6 @@ NS_ASSUME_NONNULL_BEGIN

- (instancetype)initWithBridge:(RCTBridge *)bridge;

@property (nonatomic, assign) BOOL emulateUnlessSupported;

@end

NS_ASSUME_NONNULL_END
72 changes: 2 additions & 70 deletions React/Views/SafeAreaView/RCTSafeAreaView.m
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,6 @@ - (instancetype)initWithBridge:(RCTBridge *)bridge
{
if (self = [super initWithFrame:CGRectZero]) {
_bridge = bridge;
_emulateUnlessSupported = YES; // The default.
}

return self;
Expand All @@ -41,48 +40,10 @@ - (NSString *)description

return [NSString stringWithFormat:@"%@; safeAreaInsets = %@; appliedSafeAreaInsets = %@>",
superDescription,
NSStringFromUIEdgeInsets([self safeAreaInsetsIfSupportedAndEnabled]),
NSStringFromUIEdgeInsets(self.safeAreaInsets),
NSStringFromUIEdgeInsets(_currentSafeAreaInsets)];
}

- (BOOL)isSupportedByOS
{
return [self respondsToSelector:@selector(safeAreaInsets)];
}

- (UIEdgeInsets)safeAreaInsetsIfSupportedAndEnabled
{
if (self.isSupportedByOS) {
return self.safeAreaInsets;
}
return self.emulateUnlessSupported ? self.emulatedSafeAreaInsets : UIEdgeInsetsZero;
}

- (UIEdgeInsets)emulatedSafeAreaInsets
{
UIViewController *vc = self.reactViewController;

if (!vc) {
return UIEdgeInsetsZero;
}

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);
}

return safeAreaInsets;
}

static BOOL UIEdgeInsetsEqualToEdgeInsetsWithThreshold(UIEdgeInsets insets1, UIEdgeInsets insets2, CGFloat threshold)
{
return ABS(insets1.left - insets2.left) <= threshold && ABS(insets1.right - insets2.right) <= threshold &&
Expand All @@ -91,21 +52,7 @@ static BOOL UIEdgeInsetsEqualToEdgeInsetsWithThreshold(UIEdgeInsets insets1, UIE

- (void)safeAreaInsetsDidChange
{
[self invalidateSafeAreaInsets];
}

- (void)invalidateSafeAreaInsets
{
[self setSafeAreaInsets:self.safeAreaInsetsIfSupportedAndEnabled];
}

- (void)layoutSubviews
{
[super layoutSubviews];

if (!self.isSupportedByOS && self.emulateUnlessSupported) {
[self invalidateSafeAreaInsets];
}
[self setSafeAreaInsets:self.safeAreaInsets];
}

- (void)setSafeAreaInsets:(UIEdgeInsets)safeAreaInsets
Expand All @@ -120,19 +67,4 @@ - (void)setSafeAreaInsets:(UIEdgeInsets)safeAreaInsets
[_bridge.uiManager setLocalData:localData forView:self];
}

- (void)setEmulateUnlessSupported:(BOOL)emulateUnlessSupported
{
if (_emulateUnlessSupported == emulateUnlessSupported) {
return;
}

_emulateUnlessSupported = emulateUnlessSupported;

if ([self isSupportedByOS]) {
return;
}

[self invalidateSafeAreaInsets];
}

@end
2 changes: 0 additions & 2 deletions React/Views/SafeAreaView/RCTSafeAreaViewManager.m
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,6 @@ @implementation RCTSafeAreaViewManager

RCT_EXPORT_MODULE()

RCT_EXPORT_VIEW_PROPERTY(emulateUnlessSupported, BOOL)

- (UIView *)view
{
return [[RCTSafeAreaView alloc] initWithBridge:self.bridge];
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@ const {
Modal,
SafeAreaView,
StyleSheet,
Switch,
Text,
View,
} = require('react-native');
Expand All @@ -27,12 +26,10 @@ class SafeAreaViewExample extends React.Component<
{...},
{|
modalVisible: boolean,
emulateUnlessSupported: boolean,
|},
> {
state = {
modalVisible: false,
emulateUnlessSupported: true,
};

_setModalVisible = visible => {
Expand All @@ -48,21 +45,12 @@ class SafeAreaViewExample extends React.Component<
animationType="slide"
supportedOrientations={['portrait', 'landscape']}>
<View style={styles.modal}>
<SafeAreaView
style={styles.safeArea}
emulateUnlessSupported={this.state.emulateUnlessSupported}>
<SafeAreaView style={styles.safeArea}>
<View style={styles.safeAreaContent}>
<Button
onPress={this._setModalVisible.bind(this, false)}
title="Close"
/>
<Text>emulateUnlessSupported:</Text>
<Switch
onValueChange={value =>
this.setState({emulateUnlessSupported: value})
}
value={this.state.emulateUnlessSupported}
/>
</View>
</SafeAreaView>
</View>
Expand All @@ -71,13 +59,6 @@ class SafeAreaViewExample extends React.Component<
onPress={this._setModalVisible.bind(this, true)}
title="Present Modal Screen with SafeAreaView"
/>
<Text>emulateUnlessSupported:</Text>
<Switch
onValueChange={value =>
this.setState({emulateUnlessSupported: value})
}
value={this.state.emulateUnlessSupported}
/>
</View>
);
}
Expand Down

0 comments on commit c73e021

Please sign in to comment.