amis-rpc-design/node_modules/react-native/React/Base/Surface/SurfaceHostingView/RCTSurfaceHostingView.mm
2023-10-07 19:42:30 +08:00

254 lines
6.7 KiB
Plaintext

/*
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
#import "RCTSurfaceHostingView.h"
#import "RCTConstants.h"
#import "RCTDefines.h"
#import "RCTSurface.h"
#import "RCTSurfaceDelegate.h"
#import "RCTSurfaceView.h"
#import "RCTUtils.h"
@interface RCTSurfaceHostingView ()
@property (nonatomic, assign) BOOL isActivityIndicatorViewVisible;
@property (nonatomic, assign) BOOL isSurfaceViewVisible;
@end
@implementation RCTSurfaceHostingView {
UIView *_Nullable _activityIndicatorView;
UIView *_Nullable _surfaceView;
RCTSurfaceStage _stage;
}
+ (id<RCTSurfaceProtocol>)createSurfaceWithBridge:(RCTBridge *)bridge
moduleName:(NSString *)moduleName
initialProperties:(NSDictionary *)initialProperties
{
return [[RCTSurface alloc] initWithBridge:bridge moduleName:moduleName initialProperties:initialProperties];
}
RCT_NOT_IMPLEMENTED(-(instancetype)init)
RCT_NOT_IMPLEMENTED(-(instancetype)initWithFrame : (CGRect)frame)
RCT_NOT_IMPLEMENTED(-(nullable instancetype)initWithCoder : (NSCoder *)coder)
- (instancetype)initWithBridge:(RCTBridge *)bridge
moduleName:(NSString *)moduleName
initialProperties:(NSDictionary *)initialProperties
sizeMeasureMode:(RCTSurfaceSizeMeasureMode)sizeMeasureMode
{
id<RCTSurfaceProtocol> surface = [[self class] createSurfaceWithBridge:bridge
moduleName:moduleName
initialProperties:initialProperties];
if (self = [self initWithSurface:surface sizeMeasureMode:sizeMeasureMode]) {
[surface start];
}
return self;
}
- (instancetype)initWithSurface:(id<RCTSurfaceProtocol>)surface
sizeMeasureMode:(RCTSurfaceSizeMeasureMode)sizeMeasureMode
{
if (self = [super initWithFrame:CGRectZero]) {
_surface = surface;
_sizeMeasureMode = sizeMeasureMode;
_surface.delegate = self;
_stage = surface.stage;
[self _updateViews];
// For backward compatibility with RCTRootView, set a color here instead of transparent (OS default).
self.backgroundColor = [UIColor whiteColor];
}
return self;
}
- (void)dealloc
{
[_surface stop];
}
- (void)setFrame:(CGRect)frame
{
[super setFrame:frame];
CGSize minimumSize;
CGSize maximumSize;
RCTSurfaceMinimumSizeAndMaximumSizeFromSizeAndSizeMeasureMode(
self.bounds.size, _sizeMeasureMode, &minimumSize, &maximumSize);
CGRect windowFrame = [self.window convertRect:self.frame fromView:self.superview];
[_surface setMinimumSize:minimumSize maximumSize:maximumSize viewportOffset:windowFrame.origin];
}
- (CGSize)intrinsicContentSize
{
if (RCTSurfaceStageIsPreparing(_stage)) {
if (_activityIndicatorView) {
return _activityIndicatorView.intrinsicContentSize;
}
return CGSizeZero;
}
return _surface.intrinsicSize;
}
- (CGSize)sizeThatFits:(CGSize)size
{
if (RCTSurfaceStageIsPreparing(_stage)) {
if (_activityIndicatorView) {
return [_activityIndicatorView sizeThatFits:size];
}
return CGSizeZero;
}
CGSize minimumSize;
CGSize maximumSize;
RCTSurfaceMinimumSizeAndMaximumSizeFromSizeAndSizeMeasureMode(size, _sizeMeasureMode, &minimumSize, &maximumSize);
return [_surface sizeThatFitsMinimumSize:minimumSize maximumSize:maximumSize];
}
- (void)setStage:(RCTSurfaceStage)stage
{
if (stage == _stage) {
return;
}
BOOL shouldInvalidateLayout = RCTSurfaceStageIsRunning(stage) != RCTSurfaceStageIsRunning(_stage) ||
RCTSurfaceStageIsPreparing(stage) != RCTSurfaceStageIsPreparing(_stage);
_stage = stage;
if (shouldInvalidateLayout) {
[self _invalidateLayout];
[self _updateViews];
}
}
- (void)setSizeMeasureMode:(RCTSurfaceSizeMeasureMode)sizeMeasureMode
{
if (sizeMeasureMode == _sizeMeasureMode) {
return;
}
_sizeMeasureMode = sizeMeasureMode;
[self _invalidateLayout];
}
#pragma mark - isActivityIndicatorViewVisible
- (void)setIsActivityIndicatorViewVisible:(BOOL)visible
{
if (_isActivityIndicatorViewVisible == visible) {
return;
}
_isActivityIndicatorViewVisible = visible;
if (visible) {
if (_activityIndicatorViewFactory) {
_activityIndicatorView = _activityIndicatorViewFactory();
_activityIndicatorView.frame = self.bounds;
_activityIndicatorView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
[self addSubview:_activityIndicatorView];
}
} else {
[_activityIndicatorView removeFromSuperview];
_activityIndicatorView = nil;
}
}
#pragma mark - isSurfaceViewVisible
- (void)setIsSurfaceViewVisible:(BOOL)visible
{
if (_isSurfaceViewVisible == visible) {
return;
}
_isSurfaceViewVisible = visible;
if (visible) {
_surfaceView = _surface.view;
_surfaceView.frame = self.bounds;
_surfaceView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
[self addSubview:_surfaceView];
} else {
[_surfaceView removeFromSuperview];
_surfaceView = nil;
}
}
#pragma mark - activityIndicatorViewFactory
- (void)setActivityIndicatorViewFactory:(RCTSurfaceHostingViewActivityIndicatorViewFactory)activityIndicatorViewFactory
{
_activityIndicatorViewFactory = activityIndicatorViewFactory;
if (_isActivityIndicatorViewVisible) {
self.isActivityIndicatorViewVisible = NO;
self.isActivityIndicatorViewVisible = YES;
}
}
#pragma mark - UITraitCollection updates
- (void)traitCollectionDidChange:(UITraitCollection *)previousTraitCollection
{
[super traitCollectionDidChange:previousTraitCollection];
[[NSNotificationCenter defaultCenter]
postNotificationName:RCTUserInterfaceStyleDidChangeNotification
object:self
userInfo:@{
RCTUserInterfaceStyleDidChangeNotificationTraitCollectionKey : self.traitCollection,
}];
}
#pragma mark - Private stuff
- (void)_invalidateLayout
{
[self invalidateIntrinsicContentSize];
[self.superview setNeedsLayout];
}
- (void)_updateViews
{
self.isSurfaceViewVisible = RCTSurfaceStageIsRunning(_stage);
self.isActivityIndicatorViewVisible = RCTSurfaceStageIsPreparing(_stage);
}
- (void)didMoveToWindow
{
[super didMoveToWindow];
[self _updateViews];
}
#pragma mark - RCTSurfaceDelegate
- (void)surface:(__unused RCTSurface *)surface didChangeStage:(RCTSurfaceStage)stage
{
RCTExecuteOnMainQueue(^{
[self setStage:stage];
});
}
- (void)surface:(__unused RCTSurface *)surface didChangeIntrinsicSize:(__unused CGSize)intrinsicSize
{
RCTExecuteOnMainQueue(^{
[self _invalidateLayout];
});
}
@end