Size flexibility modes for RCTRootView
Reviewed By: javache Differential Revision: D2526355 fb-gh-sync-id: 095a43bc01f883fdfdad3a086a35682c20c05597
This commit is contained in:
parent
3a92f2017f
commit
46803f0617
|
@ -87,11 +87,7 @@ function renderApplication<D, P, S>(
|
|||
|
||||
var styles = StyleSheet.create({
|
||||
appContainer: {
|
||||
position: 'absolute',
|
||||
left: 0,
|
||||
top: 0,
|
||||
right: 0,
|
||||
bottom: 0,
|
||||
flex: 1,
|
||||
},
|
||||
});
|
||||
|
||||
|
|
|
@ -11,6 +11,20 @@
|
|||
|
||||
#import "RCTBridge.h"
|
||||
|
||||
/**
|
||||
* This enum is used to define size flexibility type of the root view.
|
||||
* If a dimension is flexible, the view will recalculate that dimension
|
||||
* so the content fits. Recalculations are performed when the root's frame,
|
||||
* size flexibility mode or content size changes. After a recalculation,
|
||||
* TODO:<DelegateName> will be called with the new size passed as an argument.
|
||||
*/
|
||||
typedef NS_ENUM(NSInteger, RCTRootViewSizeFlexibility) {
|
||||
RCTRootViewSizeFlexibilityNone = 0,
|
||||
RCTRootViewSizeFlexibilityWidth,
|
||||
RCTRootViewSizeFlexibilityHeight,
|
||||
RCTRootViewSizeFlexibilityWidthAndHeight,
|
||||
};
|
||||
|
||||
/**
|
||||
* This notification is sent when the first subviews are added to the root view
|
||||
* after the application has loaded. This is used to hide the `loadingView`, and
|
||||
|
@ -71,6 +85,11 @@ extern NSString *const RCTContentDidAppearNotification;
|
|||
*/
|
||||
@property (nonatomic, strong) Class executorClass;
|
||||
|
||||
/**
|
||||
* The size flexibility mode of the root view.
|
||||
*/
|
||||
@property (nonatomic, assign) RCTRootViewSizeFlexibility sizeFlexibility;
|
||||
|
||||
/**
|
||||
* The backing view controller of the root view.
|
||||
*/
|
||||
|
|
|
@ -72,6 +72,7 @@ NSString *const RCTContentDidAppearNotification = @"RCTContentDidAppearNotificat
|
|||
_initialProperties = [initialProperties copy];
|
||||
_loadingViewFadeDelay = 0.25;
|
||||
_loadingViewFadeDuration = 0.25;
|
||||
_sizeFlexibility = RCTRootViewSizeFlexibilityNone;
|
||||
|
||||
[[NSNotificationCenter defaultCenter] addObserver:self
|
||||
selector:@selector(javaScriptDidLoad:)
|
||||
|
@ -189,6 +190,12 @@ RCT_NOT_IMPLEMENTED(- (instancetype)initWithCoder:(NSCoder *)aDecoder)
|
|||
args:@[moduleName, appParameters]];
|
||||
}
|
||||
|
||||
- (void)setSizeFlexibility:(RCTRootViewSizeFlexibility)sizeFlexibility
|
||||
{
|
||||
_sizeFlexibility = sizeFlexibility;
|
||||
[self setNeedsLayout];
|
||||
}
|
||||
|
||||
- (void)layoutSubviews
|
||||
{
|
||||
[super layoutSubviews];
|
||||
|
|
|
@ -347,11 +347,26 @@ extern NSString *RCTBridgeModuleNameForClass(Class cls);
|
|||
{
|
||||
RCTAssertMainThread();
|
||||
|
||||
// The following variables have no meaning if the view is not a react root view
|
||||
RCTRootView *rootView = (RCTRootView *)[view superview];
|
||||
RCTRootViewSizeFlexibility sizeFlexibility = rootView != nil ? rootView.sizeFlexibility : RCTRootViewSizeFlexibilityNone;
|
||||
|
||||
NSNumber *reactTag = view.reactTag;
|
||||
dispatch_async(_shadowQueue, ^{
|
||||
RCTShadowView *rootShadowView = _shadowViewRegistry[reactTag];
|
||||
RCTAssert(rootShadowView != nil, @"Could not locate root view with tag #%@", reactTag);
|
||||
rootShadowView.frame = frame;
|
||||
|
||||
if (RCTIsReactRootView(reactTag)) {
|
||||
if (CGRectEqualToRect(frame, rootShadowView.frame) && rootShadowView.sizeFlexibility == sizeFlexibility) {
|
||||
// This is to prevent infinite recursion when the frame update is trigerred by TODO(8608567):<DelegateName>
|
||||
return;
|
||||
}
|
||||
rootShadowView.frame = frame;
|
||||
rootShadowView.sizeFlexibility = sizeFlexibility;
|
||||
} else {
|
||||
rootShadowView.frame = frame;
|
||||
}
|
||||
|
||||
[rootShadowView updateLayout];
|
||||
|
||||
[self batchDidComplete];
|
||||
|
@ -437,8 +452,7 @@ extern NSString *RCTBridgeModuleNameForClass(Class cls);
|
|||
// these structures in the UI-thread block. `NSMutableArray` is not thread
|
||||
// safe so we rely on the fact that we never mutate it after it's passed to
|
||||
// the main thread.
|
||||
[rootShadowView collectRootUpdatedFrames:viewsWithNewFrames
|
||||
parentConstraint:(CGSize){CSS_UNDEFINED, CSS_UNDEFINED}];
|
||||
[rootShadowView collectRootUpdatedFrames:viewsWithNewFrames];
|
||||
|
||||
// Parallel arrays are built and then handed off to main thread
|
||||
NSMutableArray *frameReactTags = [NSMutableArray arrayWithCapacity:viewsWithNewFrames.count];
|
||||
|
|
|
@ -11,6 +11,7 @@
|
|||
|
||||
#import "Layout.h"
|
||||
#import "RCTComponent.h"
|
||||
#import "RCTRootView.h"
|
||||
|
||||
@class RCTSparseArray;
|
||||
|
||||
|
@ -64,6 +65,12 @@ typedef void (^RCTApplierBlock)(RCTSparseArray *viewRegistry);
|
|||
- (void)setTopLeft:(CGPoint)topLeft;
|
||||
- (void)setSize:(CGSize)size;
|
||||
|
||||
/**
|
||||
* Size flexibility type used to find size constraints.
|
||||
* Default to RCTRootViewSizeFlexibilityNone
|
||||
*/
|
||||
@property (nonatomic, assign) RCTRootViewSizeFlexibility sizeFlexibility;
|
||||
|
||||
/**
|
||||
* Border. Defaults to { 0, 0, 0, 0 }.
|
||||
*/
|
||||
|
@ -127,8 +134,7 @@ typedef void (^RCTApplierBlock)(RCTSparseArray *viewRegistry);
|
|||
* Calculate all views whose frame needs updating after layout has been calculated.
|
||||
* The viewsWithNewFrame set contains the reactTags of the views that need updating.
|
||||
*/
|
||||
- (void)collectRootUpdatedFrames:(NSMutableSet *)viewsWithNewFrame
|
||||
parentConstraint:(CGSize)parentConstraint;
|
||||
- (void)collectRootUpdatedFrames:(NSMutableSet *)viewsWithNewFrame;
|
||||
|
||||
/**
|
||||
* Recursively apply layout to children.
|
||||
|
|
|
@ -215,9 +215,32 @@ static void RCTProcessMetaProps(const float metaProps[META_PROP_COUNT], float st
|
|||
}
|
||||
}
|
||||
|
||||
- (void)collectRootUpdatedFrames:(NSMutableSet *)viewsWithNewFrame
|
||||
parentConstraint:(__unused CGSize)parentConstraint
|
||||
|
||||
- (void)applySizeConstraints
|
||||
{
|
||||
switch (_sizeFlexibility) {
|
||||
case RCTRootViewSizeFlexibilityNone:
|
||||
break;
|
||||
case RCTRootViewSizeFlexibilityWidth:
|
||||
_cssNode->style.dimensions[CSS_WIDTH] = CSS_UNDEFINED;
|
||||
break;
|
||||
case RCTRootViewSizeFlexibilityHeight:
|
||||
_cssNode->style.dimensions[CSS_HEIGHT] = CSS_UNDEFINED;
|
||||
break;
|
||||
case RCTRootViewSizeFlexibilityWidthAndHeight:
|
||||
_cssNode->style.dimensions[CSS_WIDTH] = CSS_UNDEFINED;
|
||||
_cssNode->style.dimensions[CSS_HEIGHT] = CSS_UNDEFINED;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
- (void)collectRootUpdatedFrames:(NSMutableSet *)viewsWithNewFrame
|
||||
{
|
||||
RCTAssert(RCTIsReactRootView(self.reactTag),
|
||||
@"The method has been called on a view with react tag %@, which is not a root view", self.reactTag);
|
||||
|
||||
[self applySizeConstraints];
|
||||
|
||||
[self fillCSSNode:_cssNode];
|
||||
layoutNode(_cssNode, CSS_UNDEFINED, CSS_DIRECTION_INHERIT);
|
||||
[self applyLayoutNode:_cssNode viewsWithNewFrame:viewsWithNewFrame absolutePosition:CGPointZero];
|
||||
|
@ -245,6 +268,7 @@ static void RCTProcessMetaProps(const float metaProps[META_PROP_COUNT], float st
|
|||
if ((self = [super init])) {
|
||||
|
||||
_frame = CGRectMake(0, 0, CSS_UNDEFINED, CSS_UNDEFINED);
|
||||
_sizeFlexibility = RCTRootViewSizeFlexibilityNone;
|
||||
|
||||
for (unsigned int ii = 0; ii < META_PROP_COUNT; ii++) {
|
||||
_paddingMetaProps[ii] = CSS_UNDEFINED;
|
||||
|
|
Loading…
Reference in New Issue