Skip to content

Commit a86171a

Browse files
majakfacebook-github-bot-3
authored andcommitted
exposed a way to trigger layout on the uimanager
Summary: A component can be backed by native "node" that can change its internal state, which would result in a new UI after the next layout. Since js has no way of knowing that this has happened it wouldn't trigger a layout if nothing in js world has changed. Therefore we need a way how to trigger layout from native code. This diff does it by adding methods `layoutIfNeeded` on the uimanager and `isBatchActive` on the bridge. When `layoutIfNeeded` is called it checks whether a batch is in progress. If it is we do nothing, since at it's end layout happens. If a batch is not in progress we immidiately do layout. I went with the easiest way how to implement this - `isBatchActive` is a public method on the bridge. It's not ideal, but consistent with other methods for modules. public Reviewed By: jspahrsummers, nicklockwood Differential Revision: D2748896 fb-gh-sync-id: f3664c4af980d40a463b538e069b26c9ebad6300
1 parent 302317c commit a86171a

File tree

5 files changed

+39
-0
lines changed

5 files changed

+39
-0
lines changed

React/Base/RCTBatchedBridge.m

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -982,6 +982,11 @@ - (void)stopProfiling:(void (^)(NSData *))callback
982982
}];
983983
}
984984

985+
- (BOOL)isBatchActive
986+
{
987+
return _wasBatchActive;
988+
}
989+
985990
@end
986991

987992
@implementation RCTBatchedBridge(Deprecated)

React/Base/RCTBridge.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -163,6 +163,11 @@ RCT_EXTERN BOOL RCTBridgeModuleClassIsRegistered(Class);
163163
*/
164164
- (void)reload;
165165

166+
/**
167+
* Says whether bridge has started recieving calls from javascript.
168+
*/
169+
- (BOOL)isBatchActive;
170+
166171
@end
167172

168173
/**

React/Base/RCTBridge.m

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -287,6 +287,11 @@ - (BOOL)isValid
287287
return self.batchedBridge.valid;
288288
}
289289

290+
- (BOOL)isBatchActive
291+
{
292+
return [_batchedBridge isBatchActive];
293+
}
294+
290295
- (void)invalidate
291296
{
292297
RCTBatchedBridge *batchedBridge = self.batchedBridge;

React/Modules/RCTUIManager.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,12 @@ RCT_EXTERN NSString *const RCTUIManagerRootViewKey;
8888
*/
8989
@property (atomic, assign) BOOL unsafeFlushUIChangesBeforeBatchEnds;
9090

91+
/**
92+
* In some cases we might want to trigger layout from native side.
93+
* React won't be aware of this, so we need to make sure it happens.
94+
*/
95+
- (void)setNeedsLayout;
96+
9197
@end
9298

9399
/**

React/Modules/RCTUIManager.m

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -888,6 +888,15 @@ - (void)partialBatchDidFlush
888888
}
889889

890890
- (void)batchDidComplete
891+
{
892+
[self _layoutAndMount];
893+
}
894+
895+
/**
896+
* Sets up animations, computes layout, creates UI mounting blocks for computed layout,
897+
* runs these blocks and all other already existing blocks.
898+
*/
899+
- (void)_layoutAndMount
891900
{
892901
// Gather blocks to be executed now that all view hierarchy manipulations have
893902
// been completed (note that these may still take place before layout has finished)
@@ -962,6 +971,15 @@ - (void)flushUIBlocks
962971
}
963972
}
964973

974+
- (void)setNeedsLayout
975+
{
976+
// If there is an active batch layout will happen when batch finished, so we will wait for that.
977+
// Otherwise we immidiately trigger layout.
978+
if (![_bridge isBatchActive]) {
979+
[self _layoutAndMount];
980+
}
981+
}
982+
965983
RCT_EXPORT_METHOD(measure:(nonnull NSNumber *)reactTag
966984
callback:(RCTResponseSenderBlock)callback)
967985
{

0 commit comments

Comments
 (0)