Commit 8748b03
authored
fix(Tabs, iOS): reconcile navigation state on implicit UIKit selection changes (#3877)
## Description
On iPad, when the app transitions from compact to regular horizontal
size class (e.g. user resizes the window), the More navigation
controller disappears. UIKit restores the previously selected tab by
calling `setSelectedIndex:` internally, but no
`UITabBarControllerDelegate` methods fire — leaving `_navigationState`
out of sync with UIKit's actual selection.
This PR ensures `_navigationState` stays consistent with UIKit
regardless of how the selection changes.
Closes
software-mansion/react-native-screens-labs#1107
## Changes
- Override `setSelectedIndex:` and `setSelectedViewController:` on
`RNSTabBarController` to detect untracked selection changes
- Add a guard flag (`_isHandlingExplicitSelectionUpdate`) set during all
known selection flows (container updates, delegate handling) to prevent
double state progression
- Add `reconcileNavigationStateWithUIKitState` — when the overrides fire
without the flag, this method detects the mismatch and updates
`_navigationState` + notifies the delegate
- Add `RNSTabsNavigationStateUpdateSourceImplicit` enum value to
distinguish UIKit-initiated side-effect changes from explicit user taps
and JS prop updates
- Update `progressNavigationState:withSource:` condition from `== User`
to `!= External` so that both `User` and `Implicit` sources update
`_lastUINavigationState` (needed for correct stale update rejection)
## Test plan
Using `test-tabs-more-navigation-controller.tsx` on iPad simulator:
1. Navigate to "Second" tab
2. Tap "More" tab bar item → select "Sixth" from the More list
3. Tap "More" tab bar item again to see the More list
4. Resize the app window to regular width (More controller disappears)
5. Verify `onTabSelected` event fires with `selectedScreenKey: "Second"`
6. Verify normal tab switching (tap, JS-driven) still works — no double
events, no provenance skips
7. Verify repeated selection still triggers special effects
Also another scenario: if we skip steps 2 & 3, no state update should be
sent!
## Checklist
- [x] Included code example that can be used to test this change.
- [ ] For visual changes, included screenshots / GIFs / recordings
documenting the change.
- [x] For API changes, updated relevant public types.
- [ ] Ensured that CI passes1 parent 01375a5 commit 8748b03
3 files changed
Lines changed: 88 additions & 3 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
63 | 63 | | |
64 | 64 | | |
65 | 65 | | |
| 66 | + | |
| 67 | + | |
66 | 68 | | |
67 | 69 | | |
68 | 70 | | |
69 | 71 | | |
70 | 72 | | |
71 | 73 | | |
| 74 | + | |
| 75 | + | |
| 76 | + | |
| 77 | + | |
72 | 78 | | |
73 | 79 | | |
74 | 80 | | |
| |||
117 | 123 | | |
118 | 124 | | |
119 | 125 | | |
| 126 | + | |
| 127 | + | |
| 128 | + | |
| 129 | + | |
| 130 | + | |
| 131 | + | |
| 132 | + | |
| 133 | + | |
| 134 | + | |
| 135 | + | |
| 136 | + | |
| 137 | + | |
| 138 | + | |
| 139 | + | |
| 140 | + | |
| 141 | + | |
120 | 142 | | |
121 | 143 | | |
122 | 144 | | |
| |||
176 | 198 | | |
177 | 199 | | |
178 | 200 | | |
| 201 | + | |
179 | 202 | | |
180 | 203 | | |
| 204 | + | |
| 205 | + | |
181 | 206 | | |
182 | 207 | | |
183 | 208 | | |
| |||
351 | 376 | | |
352 | 377 | | |
353 | 378 | | |
| 379 | + | |
354 | 380 | | |
355 | 381 | | |
356 | 382 | | |
| |||
367 | 393 | | |
368 | 394 | | |
369 | 395 | | |
| 396 | + | |
370 | 397 | | |
371 | 398 | | |
372 | 399 | | |
| |||
560 | 587 | | |
561 | 588 | | |
562 | 589 | | |
563 | | - | |
| 590 | + | |
564 | 591 | | |
565 | 592 | | |
566 | 593 | | |
| |||
596 | 623 | | |
597 | 624 | | |
598 | 625 | | |
| 626 | + | |
| 627 | + | |
| 628 | + | |
| 629 | + | |
| 630 | + | |
| 631 | + | |
| 632 | + | |
| 633 | + | |
| 634 | + | |
| 635 | + | |
| 636 | + | |
| 637 | + | |
| 638 | + | |
| 639 | + | |
| 640 | + | |
| 641 | + | |
| 642 | + | |
| 643 | + | |
| 644 | + | |
| 645 | + | |
| 646 | + | |
| 647 | + | |
| 648 | + | |
| 649 | + | |
| 650 | + | |
| 651 | + | |
| 652 | + | |
| 653 | + | |
| 654 | + | |
| 655 | + | |
| 656 | + | |
| 657 | + | |
| 658 | + | |
| 659 | + | |
| 660 | + | |
| 661 | + | |
| 662 | + | |
| 663 | + | |
| 664 | + | |
| 665 | + | |
| 666 | + | |
| 667 | + | |
| 668 | + | |
| 669 | + | |
| 670 | + | |
| 671 | + | |
| 672 | + | |
| 673 | + | |
| 674 | + | |
| 675 | + | |
| 676 | + | |
| 677 | + | |
599 | 678 | | |
600 | 679 | | |
601 | 680 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
52 | 52 | | |
53 | 53 | | |
54 | 54 | | |
55 | | - | |
| 55 | + | |
| 56 | + | |
| 57 | + | |
| 58 | + | |
56 | 59 | | |
57 | 60 | | |
58 | 61 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
59 | 59 | | |
60 | 60 | | |
61 | 61 | | |
62 | | - | |
| 62 | + | |
| 63 | + | |
| 64 | + | |
| 65 | + | |
63 | 66 | | |
64 | 67 | | |
65 | 68 | | |
| |||
0 commit comments