mirror of
https://github.com/status-im/react-native.git
synced 2025-01-14 03:26:07 +00:00
Introducing <SafeAreaView>
Summary: <SafeAreaView> renders nested content and automatically applies paddings reflect the portion of the view that is not covered by navigation bars, tab bars, toolbars, and other ancestor views. Moreover, and most importantly, Safe Area's paddings feflect physical limitation of the screen, such as rounded corners or camera notches (aka sensor housing area on iPhone X). Reviewed By: mmmulani Differential Revision: D5886411 fbshipit-source-id: 7ecc7aa34de8f5527c4e59b0fb4efba3aaea28c8
This commit is contained in:
parent
8b4ed9490c
commit
983b05441d
14
Libraries/Components/SafeAreaView/SafeAreaView.android.js
Normal file
14
Libraries/Components/SafeAreaView/SafeAreaView.android.js
Normal file
@ -0,0 +1,14 @@
|
||||
/**
|
||||
* Copyright (c) 2015-present, Facebook, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This source code is licensed under the BSD-style license found in the
|
||||
* LICENSE file in the root directory of this source tree. An additional grant
|
||||
* of patent rights can be found in the PATENTS file in the same directory.
|
||||
*
|
||||
* @providesModule SafeAreaView
|
||||
* @flow
|
||||
*/
|
||||
'use strict';
|
||||
|
||||
module.exports = require('View');
|
48
Libraries/Components/SafeAreaView/SafeAreaView.ios.js
Normal file
48
Libraries/Components/SafeAreaView/SafeAreaView.ios.js
Normal file
@ -0,0 +1,48 @@
|
||||
/**
|
||||
* Copyright (c) 2015-present, Facebook, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This source code is licensed under the BSD-style license found in the
|
||||
* LICENSE file in the root directory of this source tree. An additional grant
|
||||
* of patent rights can be found in the PATENTS file in the same directory.
|
||||
*
|
||||
* @providesModule SafeAreaView
|
||||
* @flow
|
||||
* @format
|
||||
*/
|
||||
|
||||
const React = require('React');
|
||||
const ViewPropTypes = require('ViewPropTypes');
|
||||
const requireNativeComponent = require('requireNativeComponent');
|
||||
|
||||
import type {ViewProps} from 'ViewPropTypes';
|
||||
|
||||
type Props = ViewProps & {
|
||||
children: any,
|
||||
};
|
||||
|
||||
/**
|
||||
* Renders nested content and automatically applies paddings reflect the portion of the view
|
||||
* that is not covered by navigation bars, tab bars, toolbars, and other ancestor views.
|
||||
* Moreover, and most importantly, Safe Area's paddings feflect physical limitation of the screen,
|
||||
* such as rounded corners or camera notches (aka sensor housing area on iPhone X).
|
||||
*/
|
||||
class SafeAreaView extends React.Component<Props> {
|
||||
static propTypes = {
|
||||
...ViewPropTypes,
|
||||
};
|
||||
|
||||
render() {
|
||||
return <RCTSafeAreaView {...this.props} />;
|
||||
}
|
||||
}
|
||||
|
||||
const RCTSafeAreaView = requireNativeComponent('RCTSafeAreaView', {
|
||||
name: 'RCTSafeAreaView',
|
||||
displayName: 'RCTSafeAreaView',
|
||||
propTypes: {
|
||||
...ViewPropTypes,
|
||||
},
|
||||
});
|
||||
|
||||
module.exports = SafeAreaView;
|
@ -37,6 +37,7 @@ const ReactNative = {
|
||||
get PickerIOS() { return require('PickerIOS'); },
|
||||
get ProgressBarAndroid() { return require('ProgressBarAndroid'); },
|
||||
get ProgressViewIOS() { return require('ProgressViewIOS'); },
|
||||
get SafeAreaView() { return require('SafeAreaView'); },
|
||||
get ScrollView() { return require('ScrollView'); },
|
||||
get SectionList() { return require('SectionList'); },
|
||||
get SegmentedControlIOS() { return require('SegmentedControlIOS'); },
|
||||
|
18
React/Views/SafeAreaView/RCTSafeAreaShadowView.h
Normal file
18
React/Views/SafeAreaView/RCTSafeAreaShadowView.h
Normal file
@ -0,0 +1,18 @@
|
||||
/**
|
||||
* Copyright (c) 2015-present, Facebook, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This source code is licensed under the BSD-style license found in the
|
||||
* LICENSE file in the root directory of this source tree. An additional grant
|
||||
* of patent rights can be found in the PATENTS file in the same directory.
|
||||
*/
|
||||
|
||||
#import <React/RCTShadowView.h>
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
@interface RCTSafeAreaShadowView : RCTShadowView
|
||||
|
||||
@end
|
||||
|
||||
NS_ASSUME_NONNULL_END
|
44
React/Views/SafeAreaView/RCTSafeAreaShadowView.m
Normal file
44
React/Views/SafeAreaView/RCTSafeAreaShadowView.m
Normal file
@ -0,0 +1,44 @@
|
||||
/**
|
||||
* Copyright (c) 2015-present, Facebook, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This source code is licensed under the BSD-style license found in the
|
||||
* LICENSE file in the root directory of this source tree. An additional grant
|
||||
* of patent rights can be found in the PATENTS file in the same directory.
|
||||
*/
|
||||
|
||||
#import "RCTSafeAreaShadowView.h"
|
||||
|
||||
#import <React/RCTAssert.h>
|
||||
#import <yoga/Yoga.h>
|
||||
|
||||
#import "RCTSafeAreaViewLocalData.h"
|
||||
|
||||
@implementation RCTSafeAreaShadowView
|
||||
|
||||
- (void)setLocalData:(RCTSafeAreaViewLocalData *)localData
|
||||
{
|
||||
RCTAssert([localData isKindOfClass:[RCTSafeAreaViewLocalData class]],
|
||||
@"Local data object for `RCTSafeAreaShadowView` must be `RCTSafeAreaViewLocalData` instance.");
|
||||
|
||||
UIEdgeInsets insets = localData.insets;
|
||||
|
||||
super.paddingLeft = (YGValue){insets.left, YGUnitPoint};
|
||||
super.paddingRight = (YGValue){insets.right, YGUnitPoint};
|
||||
super.paddingTop = (YGValue){insets.top, YGUnitPoint};
|
||||
super.paddingBottom = (YGValue){insets.bottom, YGUnitPoint};
|
||||
|
||||
[self didSetProps:@[@"paddingLeft", @"paddingRight", @"paddingTop", @"paddingBottom"]];
|
||||
}
|
||||
|
||||
/**
|
||||
* Removing support for setting padding from any outside code
|
||||
* to prevent interferring this with local data.
|
||||
*/
|
||||
- (void)setPadding:(YGValue)value {}
|
||||
- (void)setPaddingLeft:(YGValue)value {}
|
||||
- (void)setPaddingRight:(YGValue)value {}
|
||||
- (void)setPaddingTop:(YGValue)value {}
|
||||
- (void)setPaddingBottom:(YGValue)value {}
|
||||
|
||||
@end
|
24
React/Views/SafeAreaView/RCTSafeAreaView.h
Normal file
24
React/Views/SafeAreaView/RCTSafeAreaView.h
Normal file
@ -0,0 +1,24 @@
|
||||
/**
|
||||
* Copyright (c) 2015-present, Facebook, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This source code is licensed under the BSD-style license found in the
|
||||
* LICENSE file in the root directory of this source tree. An additional grant
|
||||
* of patent rights can be found in the PATENTS file in the same directory.
|
||||
*/
|
||||
|
||||
#import <UIKit/UIKit.h>
|
||||
|
||||
#import <React/RCTView.h>
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
@class RCTBridge;
|
||||
|
||||
@interface RCTSafeAreaView : RCTView
|
||||
|
||||
- (instancetype)initWithBridge:(RCTBridge *)bridge;
|
||||
|
||||
@end
|
||||
|
||||
NS_ASSUME_NONNULL_END
|
65
React/Views/SafeAreaView/RCTSafeAreaView.m
Normal file
65
React/Views/SafeAreaView/RCTSafeAreaView.m
Normal file
@ -0,0 +1,65 @@
|
||||
/**
|
||||
* Copyright (c) 2015-present, Facebook, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This source code is licensed under the BSD-style license found in the
|
||||
* LICENSE file in the root directory of this source tree. An additional grant
|
||||
* of patent rights can be found in the PATENTS file in the same directory.
|
||||
*/
|
||||
|
||||
#import "RCTSafeAreaView.h"
|
||||
|
||||
#import <React/RCTBridge.h>
|
||||
#import <React/RCTUIManager.h>
|
||||
|
||||
#import "RCTSafeAreaViewLocalData.h"
|
||||
|
||||
@implementation RCTSafeAreaView {
|
||||
RCTBridge *_bridge;
|
||||
UIEdgeInsets _currentSafeAreaInsets;
|
||||
}
|
||||
|
||||
- (instancetype)initWithBridge:(RCTBridge *)bridge
|
||||
{
|
||||
if (self = [super initWithFrame:CGRectZero]) {
|
||||
_bridge = bridge;
|
||||
}
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
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 &&
|
||||
ABS(insets1.right - insets2.right) <= threshold &&
|
||||
ABS(insets1.top - insets2.top) <= threshold &&
|
||||
ABS(insets1.bottom - insets2.bottom) <= threshold;
|
||||
}
|
||||
|
||||
- (void)safeAreaInsetsDidChange
|
||||
{
|
||||
if (![self respondsToSelector:@selector(safeAreaInsets)]) {
|
||||
return;
|
||||
}
|
||||
|
||||
UIEdgeInsets safeAreaInsets = self.safeAreaInsets;
|
||||
|
||||
if (UIEdgeInsetsEqualToEdgeInsetsWithThreshold(safeAreaInsets, _currentSafeAreaInsets, 1.0 / RCTScreenScale())) {
|
||||
return;
|
||||
}
|
||||
|
||||
_currentSafeAreaInsets = safeAreaInsets;
|
||||
|
||||
RCTSafeAreaViewLocalData *localData =
|
||||
[[RCTSafeAreaViewLocalData alloc] initWithInsets:safeAreaInsets];
|
||||
[_bridge.uiManager setLocalData:localData forView:self];
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
@end
|
22
React/Views/SafeAreaView/RCTSafeAreaViewLocalData.h
Normal file
22
React/Views/SafeAreaView/RCTSafeAreaViewLocalData.h
Normal file
@ -0,0 +1,22 @@
|
||||
/**
|
||||
* Copyright (c) 2015-present, Facebook, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This source code is licensed under the BSD-style license found in the
|
||||
* LICENSE file in the root directory of this source tree. An additional grant
|
||||
* of patent rights can be found in the PATENTS file in the same directory.
|
||||
*/
|
||||
|
||||
#import <UIKit/UIKit.h>
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
@interface RCTSafeAreaViewLocalData : NSObject
|
||||
|
||||
- (instancetype)initWithInsets:(UIEdgeInsets)insets;
|
||||
|
||||
@property (atomic, readonly) UIEdgeInsets insets;
|
||||
|
||||
@end
|
||||
|
||||
NS_ASSUME_NONNULL_END
|
23
React/Views/SafeAreaView/RCTSafeAreaViewLocalData.m
Normal file
23
React/Views/SafeAreaView/RCTSafeAreaViewLocalData.m
Normal file
@ -0,0 +1,23 @@
|
||||
/**
|
||||
* Copyright (c) 2015-present, Facebook, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This source code is licensed under the BSD-style license found in the
|
||||
* LICENSE file in the root directory of this source tree. An additional grant
|
||||
* of patent rights can be found in the PATENTS file in the same directory.
|
||||
*/
|
||||
|
||||
#import "RCTSafeAreaViewLocalData.h"
|
||||
|
||||
@implementation RCTSafeAreaViewLocalData
|
||||
|
||||
- (instancetype)initWithInsets:(UIEdgeInsets)insets
|
||||
{
|
||||
if (self = [super init]) {
|
||||
_insets = insets;
|
||||
}
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
@end
|
18
React/Views/SafeAreaView/RCTSafeAreaViewManager.h
Normal file
18
React/Views/SafeAreaView/RCTSafeAreaViewManager.h
Normal file
@ -0,0 +1,18 @@
|
||||
/**
|
||||
* Copyright (c) 2015-present, Facebook, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This source code is licensed under the BSD-style license found in the
|
||||
* LICENSE file in the root directory of this source tree. An additional grant
|
||||
* of patent rights can be found in the PATENTS file in the same directory.
|
||||
*/
|
||||
|
||||
#import <React/RCTViewManager.h>
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
@interface RCTSafeAreaViewManager : RCTViewManager
|
||||
|
||||
@end
|
||||
|
||||
NS_ASSUME_NONNULL_END
|
30
React/Views/SafeAreaView/RCTSafeAreaViewManager.m
Normal file
30
React/Views/SafeAreaView/RCTSafeAreaViewManager.m
Normal file
@ -0,0 +1,30 @@
|
||||
/**
|
||||
* Copyright (c) 2015-present, Facebook, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This source code is licensed under the BSD-style license found in the
|
||||
* LICENSE file in the root directory of this source tree. An additional grant
|
||||
* of patent rights can be found in the PATENTS file in the same directory.
|
||||
*/
|
||||
|
||||
#import "RCTSafeAreaViewManager.h"
|
||||
|
||||
#import "RCTSafeAreaShadowView.h"
|
||||
#import "RCTSafeAreaView.h"
|
||||
#import "RCTUIManager.h"
|
||||
|
||||
@implementation RCTSafeAreaViewManager
|
||||
|
||||
RCT_EXPORT_MODULE()
|
||||
|
||||
- (UIView *)view
|
||||
{
|
||||
return [[RCTSafeAreaView alloc] initWithBridge:self.bridge];
|
||||
}
|
||||
|
||||
- (RCTSafeAreaShadowView *)shadowView
|
||||
{
|
||||
return [RCTSafeAreaShadowView new];
|
||||
}
|
||||
|
||||
@end
|
Loading…
x
Reference in New Issue
Block a user