PR Checklist
What is the current behavior?
When a Frame is attached below a direction-bearing root before Application.run(), inherited CSS direction calls requestLayout(). Reading viewController.view there eagerly loads the navigation controller before UIApplicationMain; on iOS 18.6 the resulting app terminates on TextField focus with the UIKit gesture-graph targetNode assertion.
What is the new behavior?
Use viewIfLoaded when invalidating the controller view. Layout flags, ancestor propagation and invalidation of already loaded native views remain intact. Android already invalidates only an existing native view; no public API or declaration changes are needed.
Fixes #11586.
Validation
- New unloaded-controller regression fails on the original implementation; all 7 requestLayout tests pass with the fix.
- Full
npx nx run core:test --skip-nx-cache: 568 passed, 1 skipped, 44 files passed.
- Core 9.1.3 fixture with this exact block change: prebuilt inherited LTR and explicit pre-startup
requestLayout() pass keyboard editing and cancelled/committed native Back on iPhone/iPad simulators running 18.6.
- NativeScript-Vue 3.1.2 only: direction/no-direction controls pass on iOS 18.6.
- Published vue-router-ns rc.3: inherited LTR and tabs controls pass on iOS 18.6 and 26.0.
- Explicitly forcing
controller.view before startup still crashes with the patch: the negative control isolates early view loading, without CSS direction.
- Added two real-native assertions in
apps/automated; that complete app suite was not run. Interaction coverage comes from the external Core/Vue/router fixture and XCTest runner linked below.
- Physical iPhone unavailable during this pass; dynamic RTL and arbitrary navigation hosts were not certified.
Reproduction, reversible pinned-dependency patch, XCTest sources and results: rafaelaugustos/vue-router-ns#160 (companion reproduction and evidence PR).
Video
Actual iOS 18.6 simulator recording using the published router with only this Core correction: inherited LTR, tabs control, tabs with inherited LTR. Each flow types into a TextField, reverses native Back while preserving the draft, then completes Back.
core-lazy-controller-navigation.mp4