Introduction of RCTRootViewDelegate

Reviewed By: adamjernst

Differential Revision: D2532327

fb-gh-sync-id: 0d018a6c2842f8021718fb7387ee6acb5d894645
This commit is contained in:
Pawel Sienkowski 2015-10-26 15:39:06 -07:00 committed by facebook-github-bot-7
parent 46803f0617
commit 576f5d79af
5 changed files with 88 additions and 5 deletions

View File

@ -11,12 +11,14 @@
#import "RCTBridge.h"
@protocol RCTRootViewDelegate;
/**
* 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.
* rootViewDidChangeIntrinsicSize method of the RCTRootViewDelegate will be called.
*/
typedef NS_ENUM(NSInteger, RCTRootViewSizeFlexibility) {
RCTRootViewSizeFlexibilityNone = 0,
@ -90,6 +92,17 @@ extern NSString *const RCTContentDidAppearNotification;
*/
@property (nonatomic, assign) RCTRootViewSizeFlexibility sizeFlexibility;
/**
* The size of the root view's content. This is set right before the
* rootViewDidChangeIntrinsicSize method of RCTRootViewDelegate is called.
*/
@property (readonly, nonatomic, assign) CGSize intrinsicSize;
/**
* The delegate that handles intrinsic size updates.
*/
@property (nonatomic, weak) id<RCTRootViewDelegate> delegate;
/**
* The backing view controller of the root view.
*/

View File

@ -8,6 +8,8 @@
*/
#import "RCTRootView.h"
#import "RCTRootViewDelegate.h"
#import "RCTRootViewInternal.h"
#import <objc/runtime.h>
@ -206,6 +208,14 @@ RCT_NOT_IMPLEMENTED(- (instancetype)initWithCoder:(NSCoder *)aDecoder)
};
}
- (void)setIntrinsicSize:(CGSize)intrinsicSize
{
if (!CGSizeEqualToSize(_intrinsicSize, intrinsicSize)) {
_intrinsicSize = intrinsicSize;
[_delegate rootViewDidChangeIntrinsicSize:self];
}
}
- (NSNumber *)reactTag
{
return _contentView.reactTag;

View File

@ -0,0 +1,24 @@
/**
* Copyright (c) 2015-present, Facebook, Inc.
* All rights reserved.
*
* This source code is licensed under the BSD-style license found in the
* LICENSE file in the root directory of this source tree. An additional grant
* of patent rights can be found in the PATENTS file in the same directory.
*/
#import <Foundation/Foundation.h>
@class RCTRootView;
@protocol RCTRootViewDelegate <NSObject>
/**
* Called after the root view's content is updated to a new size.
*
* The delegate can use this callback to appropriately resize the root view frame to fit the new
* content view size. The view will not resize itself. The new content size is available via the
* intrinsicSize propery of the root view.
*/
- (void)rootViewDidChangeIntrinsicSize:(RCTRootView *)rootView;
@end

View File

@ -0,0 +1,23 @@
/**
* Copyright (c) 2015-present, Facebook, Inc.
* All rights reserved.
*
* This source code is licensed under the BSD-style license found in the
* LICENSE file in the root directory of this source tree. An additional grant
* of patent rights can be found in the PATENTS file in the same directory.
*/
#import "RCTRootView.h"
/**
* The interface provides a set of functions that allow other internal framework
* classes to change the RCTRootViews's internal state.
*/
@interface RCTRootView ()
/**
* This setter should be used only by RCTUIManager on react root view size update.
*/
@property (readwrite, nonatomic, assign) CGSize intrinsicSize;
@end

View File

@ -24,6 +24,7 @@
#import "RCTLog.h"
#import "RCTProfile.h"
#import "RCTRootView.h"
#import "RCTRootViewInternal.h"
#import "RCTScrollableProtocol.h"
#import "RCTShadowView.h"
#import "RCTSparseArray.h"
@ -357,10 +358,6 @@ extern NSString *RCTBridgeModuleNameForClass(Class cls);
RCTAssert(rootShadowView != nil, @"Could not locate root view with tag #%@", reactTag);
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 {
@ -491,6 +488,22 @@ extern NSString *RCTBridgeModuleNameForClass(Class cls);
},
});
}
if (RCTIsReactRootView(shadowView.reactTag)) {
NSNumber *reactTag = shadowView.reactTag;
CGSize contentSize = shadowView.frame.size;
dispatch_async(dispatch_get_main_queue(), ^{
UIView *view = _viewRegistry[reactTag];
RCTAssert(view != nil, @"view (for ID %@) not found", reactTag);
RCTRootView *rootView = (RCTRootView *)[view superview];
RCTAssert(rootView != nil, @"View with react tag %@ has not a superview", reactTag);
rootView.intrinsicSize = contentSize;
});
}
if (block) {
[updateBlocks addObject:block];
}