amis-rpc-design/node_modules/react-native-safe-area-context/ios/Fabric/RNCSafeAreaProviderComponentView.mm
2023-10-07 19:42:30 +08:00

120 lines
3.5 KiB
Plaintext

#import "RNCSafeAreaProviderComponentView.h"
#import <react/renderer/components/safeareacontext/ComponentDescriptors.h>
#import <react/renderer/components/safeareacontext/EventEmitters.h>
#import <react/renderer/components/safeareacontext/Props.h>
#import <react/renderer/components/safeareacontext/RCTComponentViewHelpers.h>
#import <React/RCTFabricComponentsPlugins.h>
#import "RNCSafeAreaUtils.h"
using namespace facebook::react;
@interface RNCSafeAreaProviderComponentView () <RCTRNCSafeAreaProviderViewProtocol>
@end
@implementation RNCSafeAreaProviderComponentView {
UIEdgeInsets _currentSafeAreaInsets;
CGRect _currentFrame;
BOOL _initialInsetsSent;
}
- (instancetype)initWithFrame:(CGRect)frame
{
if (self = [super initWithFrame:frame]) {
static const auto defaultProps = std::make_shared<const RNCSafeAreaProviderProps>();
_props = defaultProps;
#if !TARGET_OS_TV
[NSNotificationCenter.defaultCenter addObserver:self
selector:@selector(invalidateSafeAreaInsets)
name:UIKeyboardDidShowNotification
object:nil];
[NSNotificationCenter.defaultCenter addObserver:self
selector:@selector(invalidateSafeAreaInsets)
name:UIKeyboardDidHideNotification
object:nil];
#endif
}
return self;
}
- (void)safeAreaInsetsDidChange
{
[self invalidateSafeAreaInsets];
}
- (void)invalidateSafeAreaInsets
{
// This gets called before the view size is set by react-native so
// make sure to wait so we don't set wrong insets to JS.
if (CGSizeEqualToSize(self.frame.size, CGSizeZero)) {
return;
}
UIEdgeInsets safeAreaInsets = self.safeAreaInsets;
CGRect frame = [self convertRect:self.bounds toView:nil];
if (_initialInsetsSent &&
UIEdgeInsetsEqualToEdgeInsetsWithThreshold(safeAreaInsets, _currentSafeAreaInsets, 1.0 / RCTScreenScale()) &&
CGRectEqualToRect(frame, _currentFrame)) {
return;
}
_initialInsetsSent = YES;
_currentSafeAreaInsets = safeAreaInsets;
_currentFrame = frame;
[NSNotificationCenter.defaultCenter postNotificationName:RNCSafeAreaDidChange object:self userInfo:nil];
if (_eventEmitter) {
RNCSafeAreaProviderEventEmitter::OnInsetsChange event = {
.insets =
{
.top = safeAreaInsets.top,
.left = safeAreaInsets.left,
.bottom = safeAreaInsets.bottom,
.right = safeAreaInsets.right,
},
.frame =
{
.x = frame.origin.x,
.y = frame.origin.y,
.width = frame.size.width,
.height = frame.size.height,
},
};
std::static_pointer_cast<RNCSafeAreaProviderEventEmitter const>(_eventEmitter)->onInsetsChange(event);
}
}
- (void)layoutSubviews
{
[super layoutSubviews];
[self invalidateSafeAreaInsets];
}
#pragma mark - RCTComponentViewProtocol
+ (ComponentDescriptorProvider)componentDescriptorProvider
{
return concreteComponentDescriptorProvider<RNCSafeAreaProviderComponentDescriptor>();
}
- (void)prepareForRecycle
{
[super prepareForRecycle];
_currentSafeAreaInsets = UIEdgeInsetsZero;
_currentFrame = CGRectZero;
_initialInsetsSent = NO;
}
@end
Class<RCTComponentViewProtocol> RNCSafeAreaProviderCls(void)
{
return RNCSafeAreaProviderComponentView.class;
}