Skip to content

Commit 576f5d7

Browse files
Pawel Sienkowskifacebook-github-bot-7
authored andcommitted
Introduction of RCTRootViewDelegate
Reviewed By: adamjernst Differential Revision: D2532327 fb-gh-sync-id: 0d018a6c2842f8021718fb7387ee6acb5d894645
1 parent 46803f0 commit 576f5d7

5 files changed

Lines changed: 88 additions & 5 deletions

File tree

React/Base/RCTRootView.h

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,12 +11,14 @@
1111

1212
#import "RCTBridge.h"
1313

14+
@protocol RCTRootViewDelegate;
15+
1416
/**
1517
* This enum is used to define size flexibility type of the root view.
1618
* If a dimension is flexible, the view will recalculate that dimension
1719
* so the content fits. Recalculations are performed when the root's frame,
1820
* size flexibility mode or content size changes. After a recalculation,
19-
* TODO:<DelegateName> will be called with the new size passed as an argument.
21+
* rootViewDidChangeIntrinsicSize method of the RCTRootViewDelegate will be called.
2022
*/
2123
typedef NS_ENUM(NSInteger, RCTRootViewSizeFlexibility) {
2224
RCTRootViewSizeFlexibilityNone = 0,
@@ -90,6 +92,17 @@ extern NSString *const RCTContentDidAppearNotification;
9092
*/
9193
@property (nonatomic, assign) RCTRootViewSizeFlexibility sizeFlexibility;
9294

95+
/**
96+
* The size of the root view's content. This is set right before the
97+
* rootViewDidChangeIntrinsicSize method of RCTRootViewDelegate is called.
98+
*/
99+
@property (readonly, nonatomic, assign) CGSize intrinsicSize;
100+
101+
/**
102+
* The delegate that handles intrinsic size updates.
103+
*/
104+
@property (nonatomic, weak) id<RCTRootViewDelegate> delegate;
105+
93106
/**
94107
* The backing view controller of the root view.
95108
*/

React/Base/RCTRootView.m

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@
88
*/
99

1010
#import "RCTRootView.h"
11+
#import "RCTRootViewDelegate.h"
12+
#import "RCTRootViewInternal.h"
1113

1214
#import <objc/runtime.h>
1315

@@ -206,6 +208,14 @@ - (void)layoutSubviews
206208
};
207209
}
208210

211+
- (void)setIntrinsicSize:(CGSize)intrinsicSize
212+
{
213+
if (!CGSizeEqualToSize(_intrinsicSize, intrinsicSize)) {
214+
_intrinsicSize = intrinsicSize;
215+
[_delegate rootViewDidChangeIntrinsicSize:self];
216+
}
217+
}
218+
209219
- (NSNumber *)reactTag
210220
{
211221
return _contentView.reactTag;

React/Base/RCTRootViewDelegate.h

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
/**
2+
* Copyright (c) 2015-present, Facebook, Inc.
3+
* All rights reserved.
4+
*
5+
* This source code is licensed under the BSD-style license found in the
6+
* LICENSE file in the root directory of this source tree. An additional grant
7+
* of patent rights can be found in the PATENTS file in the same directory.
8+
*/
9+
10+
#import <Foundation/Foundation.h>
11+
12+
@class RCTRootView;
13+
14+
@protocol RCTRootViewDelegate <NSObject>
15+
/**
16+
* Called after the root view's content is updated to a new size.
17+
*
18+
* The delegate can use this callback to appropriately resize the root view frame to fit the new
19+
* content view size. The view will not resize itself. The new content size is available via the
20+
* intrinsicSize propery of the root view.
21+
*/
22+
- (void)rootViewDidChangeIntrinsicSize:(RCTRootView *)rootView;
23+
24+
@end

React/Base/RCTRootViewInternal.h

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
/**
2+
* Copyright (c) 2015-present, Facebook, Inc.
3+
* All rights reserved.
4+
*
5+
* This source code is licensed under the BSD-style license found in the
6+
* LICENSE file in the root directory of this source tree. An additional grant
7+
* of patent rights can be found in the PATENTS file in the same directory.
8+
*/
9+
10+
#import "RCTRootView.h"
11+
12+
/**
13+
* The interface provides a set of functions that allow other internal framework
14+
* classes to change the RCTRootViews's internal state.
15+
*/
16+
@interface RCTRootView ()
17+
18+
/**
19+
* This setter should be used only by RCTUIManager on react root view size update.
20+
*/
21+
@property (readwrite, nonatomic, assign) CGSize intrinsicSize;
22+
23+
@end

React/Modules/RCTUIManager.m

Lines changed: 17 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
#import "RCTLog.h"
2525
#import "RCTProfile.h"
2626
#import "RCTRootView.h"
27+
#import "RCTRootViewInternal.h"
2728
#import "RCTScrollableProtocol.h"
2829
#import "RCTShadowView.h"
2930
#import "RCTSparseArray.h"
@@ -357,10 +358,6 @@ - (void)setFrame:(CGRect)frame forView:(UIView *)view
357358
RCTAssert(rootShadowView != nil, @"Could not locate root view with tag #%@", reactTag);
358359

359360
if (RCTIsReactRootView(reactTag)) {
360-
if (CGRectEqualToRect(frame, rootShadowView.frame) && rootShadowView.sizeFlexibility == sizeFlexibility) {
361-
// This is to prevent infinite recursion when the frame update is trigerred by TODO(8608567):<DelegateName>
362-
return;
363-
}
364361
rootShadowView.frame = frame;
365362
rootShadowView.sizeFlexibility = sizeFlexibility;
366363
} else {
@@ -491,6 +488,22 @@ - (RCTViewManagerUIBlock)uiBlockWithLayoutUpdateForRootView:(RCTShadowView *)roo
491488
},
492489
});
493490
}
491+
492+
if (RCTIsReactRootView(shadowView.reactTag)) {
493+
NSNumber *reactTag = shadowView.reactTag;
494+
CGSize contentSize = shadowView.frame.size;
495+
496+
dispatch_async(dispatch_get_main_queue(), ^{
497+
UIView *view = _viewRegistry[reactTag];
498+
RCTAssert(view != nil, @"view (for ID %@) not found", reactTag);
499+
500+
RCTRootView *rootView = (RCTRootView *)[view superview];
501+
RCTAssert(rootView != nil, @"View with react tag %@ has not a superview", reactTag);
502+
503+
rootView.intrinsicSize = contentSize;
504+
});
505+
}
506+
494507
if (block) {
495508
[updateBlocks addObject:block];
496509
}

0 commit comments

Comments
 (0)