From 568f49c1bba87a92e047d0078a2b187ad332d299 Mon Sep 17 00:00:00 2001 From: WoLewicki Date: Wed, 12 Aug 2020 14:10:37 +0200 Subject: [PATCH 1/2] fix: change update logic --- ios/RNSScreenStack.m | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/ios/RNSScreenStack.m b/ios/RNSScreenStack.m index 58396bb74c..8ff292c04f 100644 --- a/ios/RNSScreenStack.m +++ b/ios/RNSScreenStack.m @@ -157,24 +157,23 @@ - (void)didUpdateReactSubviews // set yet, however the layout call is already enqueued on ui thread. Enqueuing update call on the // ui queue will guarantee that the update will run after layout. dispatch_async(dispatch_get_main_queue(), ^{ - [self updateContainer]; + [self maybeAddToParentAndUpdateContainer]; }); } -- (void)didMoveToWindow +- (void)maybeAddToParentAndUpdateContainer { - [super didMoveToWindow]; - if (self.window) { - // when stack is attached to a window we do two things: - // 1) we run updateContainer – we do this because we want push view controllers to be installed - // before the VC is mounted. If we do that after it is added to parent the push updates operations - // are going to be blocked by UIKit. + [self updateContainer]; + if (_controller.parentViewController == nil) { + // when stack hasn't been added to parent VC yet we do two things: + // 1) we run updateContainer (the one above) – we do this because we want push view controllers to + // be installed before the VC is mounted. If we do that after it is added to parent the push + // updates operations are going to be blocked by UIKit. // 2) we add navigation VS to parent – this is needed for the VC lifecycle events to be dispatched // properly // 3) we again call updateContainer – this time we do this to open modal controllers. Modals // won't open in (1) because they require navigator to be added to parent. We handle that case // gracefully in setModalViewControllers and can retry opening at any point. - [self updateContainer]; [self reactAddControllerToClosestParent:_controller]; [self updateContainer]; } From 563d3c05a9eb43a56fb143cec30a4b411ec7139d Mon Sep 17 00:00:00 2001 From: WoLewicki Date: Mon, 17 Aug 2020 16:11:58 +0200 Subject: [PATCH 2/2] fix: add newest version --- ios/RNSScreenStack.m | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/ios/RNSScreenStack.m b/ios/RNSScreenStack.m index 8ff292c04f..5a490e031a 100644 --- a/ios/RNSScreenStack.m +++ b/ios/RNSScreenStack.m @@ -25,11 +25,13 @@ @implementation RNSScreenStackView { UINavigationController *_controller; NSMutableArray *_reactSubviews; __weak RNSScreenStackManager *_manager; + BOOL _hasLayout; } - (instancetype)initWithManager:(RNSScreenStackManager*)manager { if (self = [super init]) { + _hasLayout = NO; _manager = manager; _reactSubviews = [NSMutableArray new]; _presentedModals = [NSMutableArray new]; @@ -157,12 +159,30 @@ - (void)didUpdateReactSubviews // set yet, however the layout call is already enqueued on ui thread. Enqueuing update call on the // ui queue will guarantee that the update will run after layout. dispatch_async(dispatch_get_main_queue(), ^{ + self->_hasLayout = YES; [self maybeAddToParentAndUpdateContainer]; }); } +- (void)didMoveToWindow +{ + [super didMoveToWindow]; + [self maybeAddToParentAndUpdateContainer]; +} + - (void)maybeAddToParentAndUpdateContainer { + if (self.window && !_hasLayout) { + // We wait with adding to parent controller until the stack is mounted and has its initial + // layout done. + // If we add it before layout, some of the items (specifically items from the navigation bar), + // won't be able to position properly. Also the position and size of such items, even if it + // happens to change, won't be properly updated (this is perhaps some internal issue of UIKit). + // If we add it when window is not attached, some of the view transitions will be bloced (i.e. + // modal transitions) and the internal view controler's state will get out of sync with what's + // on screen without us knowing. + return; + } [self updateContainer]; if (_controller.parentViewController == nil) { // when stack hasn't been added to parent VC yet we do two things: