mirror of
https://github.com/zhigang1992/react-navigation.git
synced 2026-03-27 01:34:25 +08:00
Fix updating push native stack to avoid mid-transition related b… (#347)
This change addresses two problem. First was related to header subviews that were not laid out properly before we installed them in the header. This was causing occasional bugs where the header subviews were misplaced. The fix was to enforce container update run after layout is done (we enqueue update on ui thread directly from didUpdateReactSubviews). The second problem was related to UINavController nlifecycle methods not triggering correctly in case when updates are being made to the nav controller which isn't mounted. Previously we fixed similar issue for modal controllers where because of the fact container wasn't mounted we couldn't run modal screen updates. With push controllers the problem is very similar however the VC do update just stop getting proper lifecycle updates and warning "Unbalanced calls to begin/end appearance transitions" is displayed. The fix was similar as in the modal case, that is, we wait until container is installed in window.
This commit is contained in:
committed by
GitHub
parent
26d8dc21d2
commit
0e00f49e69
@@ -22,7 +22,6 @@
|
||||
@end
|
||||
|
||||
@implementation RNSScreenStackView {
|
||||
BOOL _needUpdate;
|
||||
UINavigationController *_controller;
|
||||
NSMutableArray<RNSScreenView *> *_reactSubviews;
|
||||
NSMutableSet<RNSScreenView *> *_dismissedScreens;
|
||||
@@ -38,7 +37,6 @@
|
||||
_dismissedScreens = [NSMutableSet new];
|
||||
_controller = [[UINavigationController alloc] init];
|
||||
_controller.delegate = self;
|
||||
_needUpdate = NO;
|
||||
[self addSubview:_controller.view];
|
||||
_controller.interactivePopGestureRecognizer.delegate = self;
|
||||
|
||||
@@ -164,7 +162,12 @@
|
||||
|
||||
- (void)didUpdateReactSubviews
|
||||
{
|
||||
[self updateContainer];
|
||||
// we need to wait until children have their layout set. At this point they don't have the layout
|
||||
// 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];
|
||||
});
|
||||
}
|
||||
|
||||
- (void)didMoveToWindow
|
||||
@@ -281,6 +284,12 @@
|
||||
return;
|
||||
}
|
||||
|
||||
// if view controller is not yet attached to window we skip updates now and run them when view
|
||||
// is attached
|
||||
if (self.window == nil) {
|
||||
return;
|
||||
}
|
||||
|
||||
UIViewController *top = controllers.lastObject;
|
||||
UIViewController *lastTop = _controller.viewControllers.lastObject;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user