You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
### ⚠️ CRITICAL: Overlay Dismissal with Native UITabBarController
377
+
378
+
When the app uses native `UITabBarController` (`@onekeyfe/react-native-tab-view`), **non-selected tabs' views are removed from the iOS window hierarchy**. This means any `RNSScreenStack` inside an inactive tab has `window=NIL` and cannot process navigation updates.
379
+
380
+
**Problem**: Calling `goBack()` to pop overlay routes (Modal, FullScreenPush) triggers React Navigation to reconcile nested stacks inside those routes. If a nested stack is inside a tab that has lost its window, the native `setPushViewControllers` is SKIPPED and retries 50 times (~5 seconds) before giving up. The navigation appears frozen until the user touches the screen.
381
+
382
+
**Rule**: When navigating from an overlay route to a tab page, **never use sequential `goBack()` calls**. Use `navigateFromOverlayToTab()` or `resetAboveMainRoute()` instead.
// ✅ ALSO CORRECT: Use resetAboveMainRoute directly
401
+
awaitpopScanModalPages();
402
+
awaitwaitForScanModalClosed();
403
+
resetAboveMainRoute(); // Atomically remove all overlay routes
404
+
navigation.switchTab(ETabRoutes.Home);
405
+
awaittimerUtils.wait(100); // Wait for navigator to settle
406
+
navigation.push(targetPage);
407
+
```
408
+
409
+
**Key utilities** (exported from `@onekeyhq/components`):
410
+
-`navigateFromOverlayToTab()` — Safe overlay-to-tab navigation with atomic reset
411
+
-`resetAboveMainRoute()` — Atomically remove all routes above Main via `CommonActions.reset`
412
+
413
+
### Why `switchTab()` alone cannot activate the target tab
414
+
415
+
When overlay routes (FullScreenPush, Modal) are stacked above Main, calling `switchTab()` only changes `UITabBarController.selectedIndex` internally. The target tab's view is **NOT** added to the window hierarchy because the overlay route's view is still the topmost visible layer. The `UITabBarController` only manages views within its own container — if that container is obscured by an overlay, the tab view stays detached.
416
+
417
+
```
418
+
Root State: [Main, FullScreenPush, Modal]
419
+
↑ overlay is topmost visible view
420
+
UITabBarController's tab views are underneath, not in window
421
+
422
+
switchTab(Home) → selectedIndex changes, but Home tab's view still has window=NIL
423
+
goBack() to pop FullScreenPush → nested stack update fails (window=NIL)
424
+
```
425
+
426
+
Therefore, **you must use `resetAboveMainRoute()` to atomically remove all overlays first**, making Main the topmost route. Only then will `switchTab()` cause the target tab's view to enter the window hierarchy.
427
+
428
+
**When to watch out**:
429
+
- Any code that calls `goBack()` on root navigator while a FullScreenPush or Modal is active
430
+
- Any flow that dismisses overlay pages and then navigates to a different tab
431
+
- Cross-tab navigation after closing settings/action center pages
0 commit comments