Skip to content

Commit

Permalink
Better support of UIKit layout stuff for RCTRootView an co.
Browse files Browse the repository at this point in the history
Summary:
Now RCTRootView is much more reliable citizen of UIKit, it got:
 * Implemented `sizeThatFits:`;
 * Implemented `instrinsicContentSize`;
 * Notifying superview via `setNeedsLayout` about changed size.

All it make possible painless integration of ReactNative-powered widgets inside existing native apps.

Reviewed By: javache

Differential Revision: D4577890

fbshipit-source-id: 9897cb002c9d658a97fd436240c2ac947ba2084b
  • Loading branch information
shergin authored and facebook-github-bot committed Feb 27, 2017
1 parent b6ca952 commit 9dccff0
Showing 1 changed file with 32 additions and 14 deletions.
46 changes: 32 additions & 14 deletions React/Base/RCTRootView.m
Expand Up @@ -46,7 +46,6 @@ @implementation RCTRootView
NSString *_moduleName; NSString *_moduleName;
NSDictionary *_launchOptions; NSDictionary *_launchOptions;
RCTRootContentView *_contentView; RCTRootContentView *_contentView;

BOOL _passThroughTouches; BOOL _passThroughTouches;
} }


Expand All @@ -60,8 +59,7 @@ - (instancetype)initWithBridge:(RCTBridge *)bridge


RCT_PROFILE_BEGIN_EVENT(RCTProfileTagAlways, @"-[RCTRootView init]", nil); RCT_PROFILE_BEGIN_EVENT(RCTProfileTagAlways, @"-[RCTRootView init]", nil);


if ((self = [super initWithFrame:CGRectZero])) { if (self = [super initWithFrame:CGRectZero]) {

self.backgroundColor = [UIColor whiteColor]; self.backgroundColor = [UIColor whiteColor];


_bridge = bridge; _bridge = bridge;
Expand Down Expand Up @@ -95,7 +93,7 @@ - (instancetype)initWithBridge:(RCTBridge *)bridge
#endif #endif


if (!_bridge.loading) { if (!_bridge.loading) {
[self bundleFinishedLoading:[_bridge batchedBridge]]; [self bundleFinishedLoading:([_bridge batchedBridge] ?: _bridge)];
} }


[self showLoadingView]; [self showLoadingView];
Expand Down Expand Up @@ -137,6 +135,8 @@ - (void)setBackgroundColor:(UIColor *)backgroundColor
_contentView.backgroundColor = backgroundColor; _contentView.backgroundColor = backgroundColor;
} }


#pragma mark - passThroughTouches

- (BOOL)passThroughTouches - (BOOL)passThroughTouches
{ {
return _contentView.passThroughTouches; return _contentView.passThroughTouches;
Expand All @@ -148,6 +148,26 @@ - (void)setPassThroughTouches:(BOOL)passThroughTouches
_contentView.passThroughTouches = passThroughTouches; _contentView.passThroughTouches = passThroughTouches;
} }


#pragma mark - Layout

- (CGSize)sizeThatFits:(CGSize)size
{
return CGSizeMake(
_sizeFlexibility & RCTRootViewSizeFlexibilityWidth ? MIN(_intrinsicSize.width, size.width) : size.width,
_sizeFlexibility & RCTRootViewSizeFlexibilityHeight ? MIN(_intrinsicSize.height, size.height) : size.height
);
}

- (void)layoutSubviews
{
[super layoutSubviews];
_contentView.frame = self.bounds;
_loadingView.center = (CGPoint){
CGRectGetMidX(self.bounds),
CGRectGetMidY(self.bounds)
};
}

- (UIViewController *)reactViewController - (UIViewController *)reactViewController
{ {
return _reactViewController ?: [super reactViewController]; return _reactViewController ?: [super reactViewController];
Expand Down Expand Up @@ -278,16 +298,6 @@ - (void)setSizeFlexibility:(RCTRootViewSizeFlexibility)sizeFlexibility
_contentView.sizeFlexibility = _sizeFlexibility; _contentView.sizeFlexibility = _sizeFlexibility;
} }


- (void)layoutSubviews
{
[super layoutSubviews];
_contentView.frame = self.bounds;
_loadingView.center = (CGPoint){
CGRectGetMidX(self.bounds),
CGRectGetMidY(self.bounds)
};
}

- (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event - (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event
{ {
// The root view itself should never receive touches // The root view itself should never receive touches
Expand Down Expand Up @@ -323,6 +333,9 @@ - (void)setIntrinsicSize:(CGSize)intrinsicSize


_intrinsicSize = intrinsicSize; _intrinsicSize = intrinsicSize;


[self invalidateIntrinsicContentSize];
[self.superview setNeedsLayout];

// Don't notify the delegate if the content remains invisible or its size has not changed // Don't notify the delegate if the content remains invisible or its size has not changed
if (bothSizesHaveAZeroDimension || sizesAreEqual) { if (bothSizesHaveAZeroDimension || sizesAreEqual) {
return; return;
Expand All @@ -331,6 +344,11 @@ - (void)setIntrinsicSize:(CGSize)intrinsicSize
[_delegate rootViewDidChangeIntrinsicSize:self]; [_delegate rootViewDidChangeIntrinsicSize:self];
} }


- (CGSize)intrinsicContentSize
{
return _intrinsicSize;
}

- (void)contentViewInvalidated - (void)contentViewInvalidated
{ {
[_contentView removeFromSuperview]; [_contentView removeFromSuperview];
Expand Down

0 comments on commit 9dccff0

Please sign in to comment.