Permalink
Browse files

Better support of UIKit layout stuff for RCTRootView an co.

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 9dccff0eda5002b49d7ff5ac45091457e5197c06
Showing with 32 additions and 14 deletions.
  1. +32 −14 React/Base/RCTRootView.m
View
@@ -46,7 +46,6 @@ @implementation RCTRootView
NSString *_moduleName;
NSDictionary *_launchOptions;
RCTRootContentView *_contentView;
BOOL _passThroughTouches;
}
@@ -60,8 +59,7 @@ - (instancetype)initWithBridge:(RCTBridge *)bridge
RCT_PROFILE_BEGIN_EVENT(RCTProfileTagAlways, @"-[RCTRootView init]", nil);
if ((self = [super initWithFrame:CGRectZero])) {
if (self = [super initWithFrame:CGRectZero]) {
self.backgroundColor = [UIColor whiteColor];
_bridge = bridge;
@@ -95,7 +93,7 @@ - (instancetype)initWithBridge:(RCTBridge *)bridge
#endif
if (!_bridge.loading) {
[self bundleFinishedLoading:[_bridge batchedBridge]];
[self bundleFinishedLoading:([_bridge batchedBridge] ?: _bridge)];
}
[self showLoadingView];
@@ -137,6 +135,8 @@ - (void)setBackgroundColor:(UIColor *)backgroundColor
_contentView.backgroundColor = backgroundColor;
}
#pragma mark - passThroughTouches
- (BOOL)passThroughTouches
{
return _contentView.passThroughTouches;
@@ -148,6 +148,26 @@ - (void)setPassThroughTouches:(BOOL)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
{
return _reactViewController ?: [super reactViewController];
@@ -278,16 +298,6 @@ - (void)setSizeFlexibility:(RCTRootViewSizeFlexibility)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
{
// The root view itself should never receive touches
@@ -323,6 +333,9 @@ - (void)setIntrinsicSize:(CGSize)intrinsicSize
_intrinsicSize = intrinsicSize;
[self invalidateIntrinsicContentSize];
[self.superview setNeedsLayout];
// Don't notify the delegate if the content remains invisible or its size has not changed
if (bothSizesHaveAZeroDimension || sizesAreEqual) {
return;
@@ -331,6 +344,11 @@ - (void)setIntrinsicSize:(CGSize)intrinsicSize
[_delegate rootViewDidChangeIntrinsicSize:self];
}
- (CGSize)intrinsicContentSize
{
return _intrinsicSize;
}
- (void)contentViewInvalidated
{
[_contentView removeFromSuperview];

0 comments on commit 9dccff0

Please sign in to comment.