mirror of
https://github.com/status-im/react-native.git
synced 2025-02-24 07:08:27 +00:00
Summary: `RCTSurfaceHostingProxyRootView` surfaces are still automatically started right after the initialization to match `RCTRootView` interface, but `RCTSurfaceHostingView` must be started explicitly now. Also fixed some internal stuff so start and register are clear and distinct. Background / initial motivation: One tricky bit - we render the template as part of init`ing the rootView, so we don't know what the surfaceId will be before hand to register the UITemplate. Two possible solutions: 1) Require start be called explicitly after initializing the rootView, and setup the context in between. 2) Do something like "setUITemplateConfigForNextSurface" before creating the rootView, and have some hook when the surfaceId is assigned that associates the surfaceId with that "next" UITemplate stuff before. (1) seems a lot cleaner, but it requires ever user of rootView to explicitly call start on it - how do you feel about that? Seems like we could also use that start call to decide if the initial render should be synchronous or not? start vs. startSync? Reviewed By: mdvacca Differential Revision: D13372914 fbshipit-source-id: 6db297870610e6c231f8a78c0dd74d584cb64910
244 lines
5.8 KiB
Plaintext
244 lines
5.8 KiB
Plaintext
/**
|
|
* Copyright (c) Facebook, Inc. and its 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 "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;
|
|
}
|
|
|
|
+ (RCTSurface *)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
|
|
{
|
|
RCTSurface *surface = [[self class] createSurfaceWithBridge:bridge moduleName:moduleName initialProperties:initialProperties];
|
|
[surface start];
|
|
return [self initWithSurface:surface sizeMeasureMode:sizeMeasureMode];
|
|
}
|
|
|
|
- (instancetype)initWithSurface:(RCTSurface *)surface sizeMeasureMode:(RCTSurfaceSizeMeasureMode)sizeMeasureMode
|
|
{
|
|
if (self = [super initWithFrame:CGRectZero]) {
|
|
_surface = surface;
|
|
_sizeMeasureMode = sizeMeasureMode;
|
|
|
|
_surface.delegate = self;
|
|
_stage = surface.stage;
|
|
[self _updateViews];
|
|
}
|
|
|
|
return self;
|
|
}
|
|
|
|
- (void)dealloc
|
|
{
|
|
[_surface stop];
|
|
}
|
|
|
|
- (void)setFrame:(CGRect)frame
|
|
{
|
|
[super setFrame:frame];
|
|
|
|
CGSize minimumSize;
|
|
CGSize maximumSize;
|
|
|
|
RCTSurfaceMinimumSizeAndMaximumSizeFromSizeAndSizeMeasureMode(
|
|
self.bounds.size,
|
|
_sizeMeasureMode,
|
|
&minimumSize,
|
|
&maximumSize
|
|
);
|
|
|
|
[_surface setMinimumSize:minimumSize
|
|
maximumSize:maximumSize];
|
|
}
|
|
|
|
- (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 - 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:(RCTSurface *)surface didChangeStage:(RCTSurfaceStage)stage
|
|
{
|
|
RCTExecuteOnMainQueue(^{
|
|
[self setStage:stage];
|
|
});
|
|
}
|
|
|
|
- (void)surface:(RCTSurface *)surface didChangeIntrinsicSize:(CGSize)intrinsicSize
|
|
{
|
|
RCTExecuteOnMainQueue(^{
|
|
[self _invalidateLayout];
|
|
});
|
|
}
|
|
|
|
@end
|