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

82 lines
2.2 KiB
Objective-C

#import "RNCSafeAreaProvider.h"
#import <React/RCTBridge.h>
#import <React/RCTUIManager.h>
#import "RNCSafeAreaUtils.h"
@implementation RNCSafeAreaProvider {
UIEdgeInsets _currentSafeAreaInsets;
CGRect _currentFrame;
BOOL _initialInsetsSent;
}
- (instancetype)init
{
if ((self = [super init])) {
#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];
self.onInsetsChange(@{
@"insets" : @{
@"top" : @(safeAreaInsets.top),
@"right" : @(safeAreaInsets.right),
@"bottom" : @(safeAreaInsets.bottom),
@"left" : @(safeAreaInsets.left),
},
@"frame" : @{
@"x" : @(frame.origin.x),
@"y" : @(frame.origin.y),
@"width" : @(frame.size.width),
@"height" : @(frame.size.height),
},
});
}
- (void)layoutSubviews
{
[super layoutSubviews];
[self invalidateSafeAreaInsets];
}
@end