@apexnative/navigation 1.0.0-alpha.0 → 1.0.0-alpha.10
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/ApexNavigation.podspec +2 -1
- package/CHANGELOG.md +128 -0
- package/README.md +147 -51
- package/android/CLAUDE.md +78 -25
- package/android/CORE.md +49 -25
- package/android/RECIPES.md +13 -6
- package/android/consumer-rules.pro +6 -0
- package/android/src/main/java/dev/apexnative/navigation/NavigationActivity.kt +85 -10
- package/android/src/main/java/dev/apexnative/navigation/NavigationApplication.kt +34 -13
- package/android/src/main/java/dev/apexnative/navigation/layout/LayoutChecks.kt +5 -1
- package/android/src/main/java/dev/apexnative/navigation/layout/LayoutNode.kt +6 -2
- package/android/src/main/java/dev/apexnative/navigation/nativescreen/NativeScreenContext.kt +2 -2
- package/android/src/main/java/dev/apexnative/navigation/options/AnimationsOptions.kt +2 -2
- package/android/src/main/java/dev/apexnative/navigation/options/BottomTabOptions.kt +1 -1
- package/android/src/main/java/dev/apexnative/navigation/options/BottomTabsOptions.kt +13 -8
- package/android/src/main/java/dev/apexnative/navigation/options/ButtonMenuOptions.kt +2 -2
- package/android/src/main/java/dev/apexnative/navigation/options/ButtonOptions.kt +3 -3
- package/android/src/main/java/dev/apexnative/navigation/options/HardwareBackButtonOptions.kt +9 -1
- package/android/src/main/java/dev/apexnative/navigation/options/LargeTitleOptions.kt +1 -1
- package/android/src/main/java/dev/apexnative/navigation/options/LayoutAnimation.kt +1 -1
- package/android/src/main/java/dev/apexnative/navigation/options/OptionKey.kt +18 -0
- package/android/src/main/java/dev/apexnative/navigation/options/OptionPaths.kt +91 -0
- package/android/src/main/java/dev/apexnative/navigation/options/OptionsCache.kt +8 -4
- package/android/src/main/java/dev/apexnative/navigation/options/SheetOptions.kt +7 -4
- package/android/src/main/java/dev/apexnative/navigation/options/SideMenuOptions.kt +6 -1
- package/android/src/main/java/dev/apexnative/navigation/options/StackAnimationOptions.kt +40 -2
- package/android/src/main/java/dev/apexnative/navigation/options/StatusBarOptions.kt +7 -3
- package/android/src/main/java/dev/apexnative/navigation/options/TitleOptions.kt +2 -2
- package/android/src/main/java/dev/apexnative/navigation/options/TopBarAppearanceOptions.kt +1 -1
- package/android/src/main/java/dev/apexnative/navigation/options/TopBarOptions.kt +16 -7
- package/android/src/main/java/dev/apexnative/navigation/options/UserChoices.kt +159 -0
- package/android/src/main/java/dev/apexnative/navigation/react/CommandAnswer.kt +29 -36
- package/android/src/main/java/dev/apexnative/navigation/react/CommandContract.kt +59 -0
- package/android/src/main/java/dev/apexnative/navigation/react/ContentHeights.kt +95 -0
- package/android/src/main/java/dev/apexnative/navigation/react/ContentMounts.kt +66 -0
- package/android/src/main/java/dev/apexnative/navigation/react/ErrorTexts.kt +75 -60
- package/android/src/main/java/dev/apexnative/navigation/react/Hinge.kt +35 -23
- package/android/src/main/java/dev/apexnative/navigation/react/NavigationTurboModule.kt +12 -7
- package/android/src/main/java/dev/apexnative/navigation/react/OptionsCommands.kt +42 -4
- package/android/src/main/java/dev/apexnative/navigation/react/PendingCalls.kt +48 -0
- package/android/src/main/java/dev/apexnative/navigation/react/ReactView.kt +54 -20
- package/android/src/main/java/dev/apexnative/navigation/react/ReloadCoordinator.kt +7 -6
- package/android/src/main/java/dev/apexnative/navigation/react/ScreenEnvironment.kt +177 -0
- package/android/src/main/java/dev/apexnative/navigation/react/ScreenRegions.kt +19 -50
- package/android/src/main/java/dev/apexnative/navigation/react/ScrollEvents.kt +49 -128
- package/android/src/main/java/dev/apexnative/navigation/react/events/AppearanceDispatcher.kt +50 -81
- package/android/src/main/java/dev/apexnative/navigation/react/events/EventContract.kt +226 -0
- package/android/src/main/java/dev/apexnative/navigation/react/events/EventEmitter.kt +135 -94
- package/android/src/main/java/dev/apexnative/navigation/react/events/NavigationState.kt +154 -0
- package/android/src/main/java/dev/apexnative/navigation/react/events/ScreenAppearance.kt +0 -6
- package/android/src/main/java/dev/apexnative/navigation/safearea/SafeAreaView.kt +12 -10
- package/android/src/main/java/dev/apexnative/navigation/slots/SlotContainers.kt +10 -7
- package/android/src/main/java/dev/apexnative/navigation/slots/SlotScreenView.kt +39 -19
- package/android/src/main/java/dev/apexnative/navigation/slots/SlotView.kt +16 -4
- package/android/src/main/java/dev/apexnative/navigation/slots/SlotViews.kt +40 -0
- package/android/src/main/java/dev/apexnative/navigation/utils/ImageKey.kt +66 -0
- package/android/src/main/java/dev/apexnative/navigation/utils/ImageLoader.kt +7 -89
- package/android/src/main/java/dev/apexnative/navigation/utils/ImageRequests.kt +76 -0
- package/android/src/main/java/dev/apexnative/navigation/utils/MaterialTheme.kt +5 -6
- package/android/src/main/java/dev/apexnative/navigation/utils/OptionImages.kt +262 -0
- package/android/src/main/java/dev/apexnative/navigation/utils/SystemAnimations.kt +36 -0
- package/android/src/main/java/dev/apexnative/navigation/utils/UiUtils.kt +3 -3
- package/android/src/main/java/dev/apexnative/navigation/utils/ViewController.kt +3 -1
- package/android/src/main/java/dev/apexnative/navigation/utils/ViewExtensions.kt +0 -13
- package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/arrangement/ArrangementController.kt +10 -7
- package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/arrangement/SecondaryScreenPresenter.kt +13 -5
- package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/bottomtabs/AppliedTabCalls.kt +49 -0
- package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/bottomtabs/BottomTabsCollapseBehavior.kt +5 -3
- package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/bottomtabs/BottomTabsController.kt +108 -34
- package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/bottomtabs/BottomTabsPresenter.kt +25 -24
- package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/bottomtabs/CustomTabRowGeometry.kt +22 -0
- package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/bottomtabs/TabItems.kt +3 -3
- package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/bottomtabs/TabsRoom.kt +0 -5
- package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/component/ComponentPresenter.kt +28 -7
- package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/component/ComponentViewController.kt +12 -9
- package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/component/ContentReadiness.kt +2 -2
- package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/component/RenderWait.kt +27 -7
- package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/component/ScreenFrame.kt +1 -1
- package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/component/ScreenReadiness.kt +103 -56
- package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/component/ScreenSafeArea.kt +29 -11
- package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/externalcomponent/ExternalComponentViewController.kt +2 -6
- package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/modal/ModalAnimations.kt +22 -24
- package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/modal/ModalCoordinator.kt +109 -21
- package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/modal/ModalRecord.kt +21 -6
- package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/modal/ModalSheet.kt +476 -73
- package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/modal/ModalViews.kt +57 -25
- package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/modal/SheetBack.kt +42 -0
- package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/modal/SheetStops.kt +83 -0
- package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/navigator/BackCallbackCheck.kt +50 -0
- package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/navigator/BackCallbackState.kt +49 -14
- package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/navigator/Navigator.kt +71 -12
- package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/navigator/RootCoordinator.kt +37 -11
- package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/overlay/OverlayCoordinator.kt +10 -8
- package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/parent/Capabilities.kt +11 -4
- package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/parent/ContainerBackground.kt +3 -3
- package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/parent/ParentController.kt +6 -6
- package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/sidemenu/SideMenuController.kt +42 -9
- package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/sidemenu/SideMenuMotion.kt +19 -8
- package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/sidemenu/SideMenuPresenter.kt +16 -7
- package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/sidemenu/SideMenuRules.kt +43 -4
- package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/splitview/SplitPanes.kt +23 -0
- package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/splitview/SplitViewController.kt +77 -17
- package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/stack/BackPreview.kt +315 -0
- package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/stack/PreparedFrame.kt +3 -3
- package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/stack/StackCommands.kt +30 -20
- package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/stack/StackController.kt +216 -18
- package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/stack/StackDisplay.kt +26 -1
- package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/stack/StackQueue.kt +149 -41
- package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/stack/StackTransitions.kt +26 -8
- package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/stack/StackViews.kt +115 -6
- package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/stack/fab/FabMotion.kt +142 -0
- package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/stack/fab/FabPresenter.kt +222 -48
- package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/stack/search/ScreenSearch.kt +3 -5
- package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/stack/search/StackSearchPresenter.kt +30 -34
- package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/stack/topbar/BarComponents.kt +5 -51
- package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/stack/topbar/BarRowTransition.kt +3 -2
- package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/stack/topbar/ButtonPlaces.kt +11 -5
- package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/stack/topbar/MenuChecks.kt +13 -56
- package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/stack/topbar/TopBarPresenter.kt +219 -54
- package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/stack/topbar/TopBarVisibility.kt +9 -2
- package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/viewcontroller/ScrollEventListener.kt +6 -9
- package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/viewcontroller/ViewController.kt +75 -21
- package/android/src/main/java/dev/apexnative/navigation/views/animations/AnimationLayer.kt +73 -0
- package/android/src/main/java/dev/apexnative/navigation/views/animations/Curves.kt +29 -11
- package/android/src/main/java/dev/apexnative/navigation/views/animations/ValueInterpolation.kt +14 -0
- package/android/src/main/java/dev/apexnative/navigation/views/bottomtabs/BottomTabs.kt +9 -7
- package/android/src/main/java/dev/apexnative/navigation/views/bottomtabs/BottomTabsLayout.kt +61 -2
- package/android/src/main/java/dev/apexnative/navigation/views/bottomtabs/CustomBottomTabItemView.kt +0 -5
- package/android/src/main/java/dev/apexnative/navigation/views/bottomtabs/CustomTabRow.kt +72 -10
- package/android/src/main/java/dev/apexnative/navigation/views/element/ElementStep.kt +31 -0
- package/android/src/main/java/dev/apexnative/navigation/views/element/ElementTransitions.kt +143 -135
- package/android/src/main/java/dev/apexnative/navigation/views/element/TargetsWait.kt +13 -5
- package/android/src/main/java/dev/apexnative/navigation/views/element/TransitionLayer.kt +37 -112
- package/android/src/main/java/dev/apexnative/navigation/views/element/TransitionTargets.kt +9 -6
- package/android/src/main/java/dev/apexnative/navigation/views/element/TransitionViews.kt +100 -0
- package/android/src/main/java/dev/apexnative/navigation/views/element/animators/ElementPictures.kt +112 -4
- package/android/src/main/java/dev/apexnative/navigation/views/element/animators/FlightGeometry.kt +346 -36
- package/android/src/main/java/dev/apexnative/navigation/views/element/animators/ImageMorph.kt +199 -0
- package/android/src/main/java/dev/apexnative/navigation/views/element/animators/SharedAnimatorFactory.kt +56 -41
- package/android/src/main/java/dev/apexnative/navigation/views/element/animators/TextMorph.kt +176 -0
- package/android/src/main/java/dev/apexnative/navigation/views/element/animators/ViewMorph.kt +108 -0
- package/android/src/main/java/dev/apexnative/navigation/views/sidemenu/SideMenuView.kt +12 -3
- package/android/src/main/java/dev/apexnative/navigation/views/stack/ScreenEdge.kt +45 -0
- package/android/src/main/java/dev/apexnative/navigation/views/stack/StackLayout.kt +140 -1
- package/android/src/main/java/dev/apexnative/navigation/views/stack/fab/Fab.kt +14 -10
- package/android/src/main/java/dev/apexnative/navigation/views/stack/fab/FabCopy.kt +85 -0
- package/android/src/main/java/dev/apexnative/navigation/views/stack/fab/FabMenu.kt +13 -0
- package/android/src/main/java/dev/apexnative/navigation/views/stack/topbar/TitleBar.kt +5 -17
- package/android/src/main/java/dev/apexnative/navigation/views/stack/topbar/TopBar.kt +73 -34
- package/android/src/main/java/dev/apexnative/navigation/views/stack/topbar/titlebar/BarButtonComponentCell.kt +6 -6
- package/android/src/main/java/dev/apexnative/navigation/views/stack/topbar/titlebar/BarButtonView.kt +113 -0
- package/android/src/main/java/dev/apexnative/navigation/views/stack/topbar/titlebar/BarMenu.kt +219 -0
- package/android/src/main/java/dev/apexnative/navigation/views/stack/topbar/titlebar/ButtonBar.kt +125 -178
- package/android/src/main/java/dev/apexnative/navigation/views/stack/topbar/titlebar/ButtonMenus.kt +34 -64
- package/android/src/main/java/dev/apexnative/navigation/views/stack/topbar/titlebar/ButtonRow.kt +216 -0
- package/android/src/main/jni/ANNContentHeights.cpp +82 -0
- package/android/src/main/res/drawable/apex_navigation_ic_arrow_right.xml +14 -0
- package/android/src/main/res/layout/apex_navigation_menu_header.xml +19 -0
- package/android/src/main/res/layout/apex_navigation_menu_item.xml +68 -0
- package/android/src/main/res/values/styles.xml +1 -1
- package/android/src/main/res/values-night/styles.xml +1 -1
- package/cli/app.js +1 -1
- package/cli/doctor/checks/app.js +77 -14
- package/cli/doctor/checks/splash.js +4 -22
- package/cli/migrate/native.js +18 -0
- package/cli/project.js +10 -2
- package/cli/setup/index.js +18 -0
- package/cli/setup/source.js +2 -1
- package/cli/setup/steps/appDelegate.js +66 -11
- package/cli/setup/steps/mainApplication.js +134 -19
- package/cli/setup/steps/metro.js +46 -0
- package/cli/setup/steps/sceneDelegate.js +108 -0
- package/cli/splash/index.js +3 -1
- package/cli/upgrade/changelog.js +2 -2
- package/docs-md/architecture/native-screens.md +4 -0
- package/docs-md/architecture/theme-and-context.md +131 -12
- package/docs-md/architecture/transitions.md +58 -12
- package/docs-md/containers/modals.md +8 -4
- package/docs-md/containers/overlays.md +3 -1
- package/docs-md/containers/side-menu.md +19 -2
- package/docs-md/containers/tabs.md +5 -1
- package/docs-md/flows/bottom-sheets.md +4 -2
- package/docs-md/flows/forms-in-a-modal.md +1 -1
- package/docs-md/fundamentals/screens-and-props.md +9 -1
- package/docs-md/fundamentals/starting-the-app.md +1 -1
- package/docs-md/guides/cli.md +4 -3
- package/docs-md/guides/deep-links.md +15 -33
- package/docs-md/help/glossary.md +4 -4
- package/docs-md/help/troubleshooting.md +44 -6
- package/docs-md/index.json +57 -1
- package/docs-md/migration/from-expo-router.md +1 -1
- package/docs-md/migration/from-react-native-navigation.md +9 -3
- package/docs-md/migration/from-react-navigation.md +2 -2
- package/docs-md/screen-ui/back-and-gestures.md +46 -2
- package/docs-md/screen-ui/bar-buttons.md +5 -5
- package/docs-md/screen-ui/search.md +1 -1
- package/docs-md/screen-ui/system-ui.md +17 -12
- package/docs-md/screen-ui/toolbar-and-fab.md +4 -2
- package/docs-md/screen-ui/top-bar.md +8 -4
- package/docs-md/start/installation.md +21 -3
- package/ios/Animations/ANNFrameDriver.h +55 -15
- package/ios/Animations/ANNFrameDriver.mm +216 -60
- package/ios/Animations/ANNTransitionAnimator.h +26 -5
- package/ios/Animations/ANNTransitionAnimator.mm +61 -13
- package/ios/Animations/ANNTransitionPlan.h +2 -2
- package/ios/Animations/ANNTransitionPlan.mm +10 -0
- package/ios/Animations/ANNTransitionWait.mm +6 -7
- package/ios/Animations/Elements/ANNElementFinder.h +57 -0
- package/ios/Animations/Elements/ANNElementFinder.mm +174 -2
- package/ios/Animations/Elements/ANNElementTransition.h +10 -8
- package/ios/Animations/Elements/ANNElementTransition.mm +19 -21
- package/ios/Animations/Elements/ANNSharedElementFlight.h +16 -11
- package/ios/Animations/Elements/ANNSharedElementFlight.mm +308 -69
- package/ios/Animations/Interpolators/ANNInterpolate.h +2 -30
- package/ios/Animations/Interpolators/ANNTransformParts.h +48 -0
- package/ios/Animations/Interpolators/ANNTransformParts.mm +507 -0
- package/ios/Animations/Interpolators/ANNViewTracks.h +9 -6
- package/ios/Animations/Interpolators/ANNViewTracks.mm +100 -30
- package/ios/CLAUDE.md +60 -24
- package/ios/CORE.md +44 -34
- package/ios/Contract/ANNCommandAnswer.h +13 -5
- package/ios/Contract/ANNCommandAnswer.mm +40 -32
- package/ios/Contract/ANNCommandContract.h +15 -0
- package/ios/Contract/ANNCommandContract.mm +78 -0
- package/ios/Contract/ANNCommandRunner.h +10 -9
- package/ios/Contract/ANNCommandRunner.mm +22 -28
- package/ios/Contract/ANNErrorTexts.h +6 -2
- package/ios/Contract/ANNErrorTexts.mm +18 -10
- package/ios/Contract/ANNLayoutNode.h +3 -3
- package/ios/Contract/ANNLayoutReader.h +3 -3
- package/ios/Core/ANNAppDelegate.mm +0 -2
- package/ios/Core/ANNAppearanceDispatcher.h +5 -4
- package/ios/Core/ANNAppearanceDispatcher.mm +12 -1
- package/ios/Core/ANNDeepLinkQueue.h +22 -2
- package/ios/Core/ANNDeepLinkQueue.mm +121 -14
- package/ios/Core/ANNErrorHandler.h +9 -4
- package/ios/Core/ANNErrorHandler.mm +20 -2
- package/ios/Core/ANNEventContract.h +246 -0
- package/ios/Core/ANNEventContract.mm +225 -0
- package/ios/Core/ANNEventEmitter.h +6 -2
- package/ios/Core/ANNEventEmitter.mm +117 -80
- package/ios/Core/ANNHinge.h +6 -0
- package/ios/Core/ANNHinge.mm +15 -4
- package/ios/Core/ANNJavaScriptCalls.h +33 -0
- package/ios/Core/ANNJavaScriptCalls.mm +52 -0
- package/ios/Core/ANNLayoutProtocol.h +5 -5
- package/ios/Core/ANNNavigationState.h +7 -5
- package/ios/Core/ANNNavigationState.mm +8 -7
- package/ios/Core/ANNNodeHelper.h +32 -12
- package/ios/Core/ANNNodeHelper.mm +100 -3
- package/ios/Core/ANNParking.h +5 -4
- package/ios/Core/ANNReloadCoordinator.mm +5 -12
- package/ios/Core/ANNRenderWait.h +20 -6
- package/ios/Core/ANNRenderWait.mm +143 -56
- package/ios/Core/ANNSceneDelegate.mm +25 -15
- package/ios/Core/ANNSystemUI.h +3 -2
- package/ios/Core/ANNSystemUI.mm +7 -0
- package/ios/Core/ANNUtils.h +7 -0
- package/ios/Core/ANNUtils.mm +10 -0
- package/ios/Core/ApexNavigation+Internal.h +1 -1
- package/ios/Core/ApexNavigation.mm +7 -6
- package/ios/Core/UIViewController+LayoutProtocol.h +9 -2
- package/ios/Core/UIViewController+LayoutProtocol.mm +8 -0
- package/ios/Layouts/Arrangement/ANNArrangementState.h +2 -17
- package/ios/Layouts/Arrangement/ANNArrangementState.mm +0 -38
- package/ios/Layouts/Arrangement/ANNArrangementViewController.mm +10 -8
- package/ios/Layouts/Modal/ANNModalCoordinator.h +1 -1
- package/ios/Layouts/Modal/ANNModalCoordinator.mm +57 -16
- package/ios/Layouts/Modal/ANNModalPresentation.h +8 -5
- package/ios/Layouts/Modal/ANNModalPresentation.mm +12 -12
- package/ios/Layouts/Modal/ANNSheetPresenter.mm +83 -1
- package/ios/Layouts/Overlay/ANNOverlayCoordinator.mm +2 -8
- package/ios/Layouts/Root/ANNRootCoordinator.mm +58 -19
- package/ios/Layouts/Root/ANNSplashViewController.h +5 -3
- package/ios/Layouts/Root/ANNSplashViewController.mm +147 -0
- package/ios/Layouts/Screen/ANNComponentPresenter.h +11 -3
- package/ios/Layouts/Screen/ANNComponentPresenter.mm +34 -6
- package/ios/Layouts/Screen/ANNComponentViewController.h +15 -13
- package/ios/Layouts/Screen/ANNComponentViewController.mm +130 -75
- package/ios/Layouts/Screen/ANNNativeScreenContext.mm +7 -5
- package/ios/Layouts/Screen/ANNPreviewInteraction.h +7 -4
- package/ios/Layouts/Screen/ANNPreviewInteraction.mm +72 -10
- package/ios/Layouts/Screen/ANNScreenEnvironment.h +63 -0
- package/ios/Layouts/Screen/ANNScreenEnvironment.mm +181 -0
- package/ios/Layouts/Screen/ANNScreenPlace.h +53 -0
- package/ios/Layouts/Screen/ANNScreenPlace.mm +205 -0
- package/ios/Layouts/Screen/ANNScreenRegions.h +3 -18
- package/ios/Layouts/Screen/ANNScreenRegions.mm +9 -44
- package/ios/Layouts/Screen/ANNScreenSafeArea.h +4 -9
- package/ios/Layouts/Screen/ANNScreenSafeArea.mm +14 -16
- package/ios/Layouts/Screen/ANNScreenSettling.h +32 -0
- package/ios/Layouts/Screen/ANNScreenSettling.mm +137 -0
- package/ios/Layouts/SideMenu/ANNSideMenuTypes.h +8 -0
- package/ios/Layouts/SideMenu/ANNSideMenuViewController.mm +83 -14
- package/ios/Layouts/SplitView/ANNSplitViewCommands.h +3 -2
- package/ios/Layouts/SplitView/ANNSplitViewCommands.mm +105 -39
- package/ios/Layouts/SplitView/ANNSplitViewController.mm +7 -8
- package/ios/Layouts/Stack/ANNPreviewPush.h +7 -6
- package/ios/Layouts/Stack/ANNPreviewPush.mm +142 -27
- package/ios/Layouts/Stack/ANNStackAnimatingDelegate.h +11 -2
- package/ios/Layouts/Stack/ANNStackAnimatingDelegate.mm +14 -7
- package/ios/Layouts/Stack/ANNStackCommands.mm +1 -0
- package/ios/Layouts/Stack/ANNStackController.h +8 -0
- package/ios/Layouts/Stack/ANNStackController.mm +184 -16
- package/ios/Layouts/Stack/ANNStackQueue.h +5 -2
- package/ios/Layouts/Stack/ANNStackQueue.mm +56 -43
- package/ios/Layouts/Stack/ANNSwipePopInteraction.h +26 -0
- package/ios/Layouts/Stack/ANNSwipePopInteraction.mm +185 -0
- package/ios/Layouts/Stack/InteractivePopGestureDelegate.mm +28 -4
- package/ios/Layouts/Stack/UINavigationController+ANNCommands.h +4 -2
- package/ios/Layouts/Stack/UINavigationController+ANNCommands.mm +2 -3
- package/ios/Layouts/Tabs/ANNBottomTabItemBuilder.h +4 -0
- package/ios/Layouts/Tabs/ANNBottomTabItemBuilder.mm +11 -0
- package/ios/Layouts/Tabs/ANNBottomTabsAccessoryView.h +12 -1
- package/ios/Layouts/Tabs/ANNBottomTabsAccessoryView.mm +23 -0
- package/ios/Layouts/Tabs/ANNBottomTabsController.h +3 -0
- package/ios/Layouts/Tabs/ANNBottomTabsController.mm +237 -57
- package/ios/Layouts/Tabs/ANNBottomTabsCustomRow.mm +8 -3
- package/ios/Layouts/Tabs/ANNBottomTabsPresenter.h +6 -2
- package/ios/Layouts/Tabs/ANNBottomTabsPresenter.mm +232 -43
- package/ios/Layouts/Tabs/ANNTabsDesign.h +6 -5
- package/ios/Layouts/Tabs/ANNTabsDesign.mm +9 -1
- package/ios/Layouts/Tabs/UITabBar+utils.h +5 -5
- package/ios/Layouts/Tabs/UITabBar+utils.mm +32 -13
- package/ios/Options/ANNAnimationOptions.h +2 -1
- package/ios/Options/ANNAnimationOptions.mm +1 -1
- package/ios/Options/ANNBottomTabsOptions.h +2 -0
- package/ios/Options/ANNBottomTabsOptions.mm +1 -0
- package/ios/Options/ANNOptions.h +25 -0
- package/ios/Options/ANNOptions.mm +157 -1
- package/ios/Options/ANNOptionsCache.h +7 -6
- package/ios/Options/ANNOptionsReader.mm +108 -0
- package/ios/Options/ANNSearchBarOptions.h +4 -3
- package/ios/Options/ANNSheetOptions.h +4 -1
- package/ios/Options/ANNSideMenuOptions.h +2 -0
- package/ios/Options/ANNSideMenuOptions.mm +2 -0
- package/ios/Options/ANNStackPopAnimationOptions.h +13 -0
- package/ios/Options/ANNStackPopAnimationOptions.mm +11 -0
- package/ios/Options/ANNUserChoice.h +57 -0
- package/ios/Options/ANNUserChoice.mm +44 -0
- package/ios/Options/Params/ANNImageSource.h +61 -0
- package/ios/Options/Params/ANNImageSource.mm +101 -0
- package/ios/Options/Params/ANNOptionImages.h +37 -0
- package/ios/Options/Params/ANNOptionImages.mm +284 -0
- package/ios/Options/Params/ANNParam.h +15 -0
- package/ios/Options/Params/ANNParam.mm +61 -0
- package/ios/Options/Params/Color.h +3 -0
- package/ios/Options/Params/Color.mm +21 -0
- package/ios/Options/Params/ColorParser.h +4 -3
- package/ios/Options/Params/ColorParser.mm +22 -4
- package/ios/Options/Params/Image.h +15 -2
- package/ios/Options/Params/Image.mm +35 -2
- package/ios/Options/Params/ImageParser.h +5 -5
- package/ios/Options/Params/ImageParser.mm +28 -46
- package/ios/Public/ApexNavigation/ANNSceneDelegate.h +3 -0
- package/ios/Public/ApexNavigation/ApexNavigation.h +1 -1
- package/ios/RECIPES.md +13 -6
- package/ios/React/ANNReactView.mm +6 -25
- package/ios/React/ANNSafeAreaViewComponentView.mm +28 -17
- package/ios/React/ANNSurfaceHostingView.h +14 -0
- package/ios/React/ANNSurfaceHostingView.mm +144 -1
- package/ios/React/Slots/ANNSlotComponentView.mm +24 -17
- package/ios/React/Slots/ANNSlotContainers.h +14 -6
- package/ios/React/Slots/ANNSlotContainers.mm +75 -2
- package/ios/React/Slots/ANNSlotHost.mm +1 -3
- package/ios/React/Slots/ANNSlotScreenView.mm +8 -2
- package/ios/TopBar/ANNBackButtonPresenter.mm +6 -5
- package/ios/TopBar/ANNBarAppearance.h +2 -1
- package/ios/TopBar/ANNBarAppearance.mm +111 -30
- package/ios/TopBar/ANNBarBackgroundComponent.mm +16 -0
- package/ios/TopBar/ANNBarButtonComponentView.h +4 -4
- package/ios/TopBar/ANNBarButtonComponentView.mm +1 -1
- package/ios/TopBar/ANNBarButtons.h +14 -8
- package/ios/TopBar/ANNBarButtons.mm +397 -80
- package/ios/TopBar/ANNIconButtonImage.h +1 -0
- package/ios/TopBar/ANNIconButtonImage.mm +34 -1
- package/ios/TopBar/ANNLargeTitlePresenter.h +13 -0
- package/ios/TopBar/ANNLargeTitlePresenter.mm +50 -7
- package/ios/TopBar/ANNMainList.h +3 -0
- package/ios/TopBar/ANNMainList.mm +4 -0
- package/ios/TopBar/ANNScrollEdgeEffects.h +22 -6
- package/ios/TopBar/ANNScrollEdgeEffects.mm +123 -16
- package/ios/TopBar/ANNSearchPresenter.mm +172 -21
- package/ios/TopBar/ANNSearchResultsViewController.mm +29 -6
- package/ios/TopBar/ANNTopBarPresenter.h +8 -2
- package/ios/TopBar/ANNTopBarPresenter.mm +155 -33
- package/ios/TurboModules/ANNTurboEventEmitter.mm +4 -35
- package/ios/TurboModules/ANNTurboModule.mm +104 -33
- package/ios/cpp/react/renderer/components/ApexNavigationSpec/ANNSlotState.cpp +20 -0
- package/ios/cpp/react/renderer/components/ApexNavigationSpec/ANNSlotState.h +5 -14
- package/lib/module/ARCHITECTURE.md +40 -27
- package/lib/module/adapters/NativeANNTurboModule.js.map +1 -1
- package/lib/module/api/app/AppRegistry.js +14 -2
- package/lib/module/api/app/AppRegistry.js.map +1 -1
- package/lib/module/api/app/createNavigation.js +190 -66
- package/lib/module/api/app/createNavigation.js.map +1 -1
- package/lib/module/api/commands/commands.js +54 -6
- package/lib/module/api/commands/commands.js.map +1 -1
- package/lib/module/api/events/navigationEvents.js +6 -2
- package/lib/module/api/events/navigationEvents.js.map +1 -1
- package/lib/module/api/hooks/useNavigation.js +8 -3
- package/lib/module/api/hooks/useNavigation.js.map +1 -1
- package/lib/module/api/hooks/useSafeAreaInsets.js +4 -3
- package/lib/module/api/hooks/useSafeAreaInsets.js.map +1 -1
- package/lib/module/api/linking/dispatchedLinks.js +23 -0
- package/lib/module/api/linking/dispatchedLinks.js.map +1 -0
- package/lib/module/api/linking/linking.js +11 -0
- package/lib/module/api/linking/linking.js.map +1 -1
- package/lib/module/api/navigation.js.map +1 -1
- package/lib/module/api/options/OptionsChain.js +2 -2
- package/lib/module/api/screens/defineScreen.js +45 -3
- package/lib/module/api/screens/defineScreen.js.map +1 -1
- package/lib/module/api/screens/nativeScreens.js +31 -6
- package/lib/module/api/screens/nativeScreens.js.map +1 -1
- package/lib/module/api/screens/registerScreens.js +193 -35
- package/lib/module/api/screens/registerScreens.js.map +1 -1
- package/lib/module/api/theme/theme.js +5 -0
- package/lib/module/api/theme/theme.js.map +1 -1
- package/lib/module/engine/commands.js +51 -9
- package/lib/module/engine/commands.js.map +1 -1
- package/lib/module/engine/layout.js +20 -11
- package/lib/module/engine/layout.js.map +1 -1
- package/lib/module/engine/nativeScreens.js +9 -0
- package/lib/module/engine/nativeScreens.js.map +1 -1
- package/lib/module/engine/options.js +49 -15
- package/lib/module/engine/options.js.map +1 -1
- package/lib/module/engine/optionsChange.js +102 -0
- package/lib/module/engine/optionsChange.js.map +1 -0
- package/lib/module/engine/places.js +52 -7
- package/lib/module/engine/places.js.map +1 -1
- package/lib/module/engine/props.js +30 -1
- package/lib/module/engine/props.js.map +1 -1
- package/lib/module/engine/refresh.js +85 -0
- package/lib/module/engine/refresh.js.map +1 -0
- package/lib/module/engine/rememberedOptions.js +61 -1
- package/lib/module/engine/rememberedOptions.js.map +1 -1
- package/lib/module/engine/screens.js +77 -16
- package/lib/module/engine/screens.js.map +1 -1
- package/lib/module/interfaces/contract/commands.json +101 -0
- package/lib/module/interfaces/contract/errors.json +275 -0
- package/lib/typescript/adapters/NativeANNTurboModule.d.ts +12 -2
- package/lib/typescript/adapters/NativeANNTurboModule.d.ts.map +1 -1
- package/lib/typescript/api/app/AppRegistry.d.ts.map +1 -1
- package/lib/typescript/api/app/createNavigation.d.ts +8 -3
- package/lib/typescript/api/app/createNavigation.d.ts.map +1 -1
- package/lib/typescript/api/commands/commands.d.ts.map +1 -1
- package/lib/typescript/api/commands/presentation.d.ts +4 -3
- package/lib/typescript/api/commands/presentation.d.ts.map +1 -1
- package/lib/typescript/api/events/navigationEvents.d.ts +3 -3
- package/lib/typescript/api/events/navigationEvents.d.ts.map +1 -1
- package/lib/typescript/api/hooks/useNavigation.d.ts +1 -1
- package/lib/typescript/api/hooks/useNavigation.d.ts.map +1 -1
- package/lib/typescript/api/hooks/useSafeAreaInsets.d.ts +4 -3
- package/lib/typescript/api/hooks/useSafeAreaInsets.d.ts.map +1 -1
- package/lib/typescript/api/index.d.ts +1 -1
- package/lib/typescript/api/index.d.ts.map +1 -1
- package/lib/typescript/api/linking/dispatchedLinks.d.ts +7 -0
- package/lib/typescript/api/linking/dispatchedLinks.d.ts.map +1 -0
- package/lib/typescript/api/linking/linking.d.ts +8 -0
- package/lib/typescript/api/linking/linking.d.ts.map +1 -1
- package/lib/typescript/api/navigation.d.ts +4 -1
- package/lib/typescript/api/navigation.d.ts.map +1 -1
- package/lib/typescript/api/options/OptionsChain.d.ts +2 -2
- package/lib/typescript/api/screens/defineScreen.d.ts +23 -4
- package/lib/typescript/api/screens/defineScreen.d.ts.map +1 -1
- package/lib/typescript/api/screens/nativeScreens.d.ts +8 -1
- package/lib/typescript/api/screens/nativeScreens.d.ts.map +1 -1
- package/lib/typescript/api/screens/registerScreens.d.ts.map +1 -1
- package/lib/typescript/api/theme/theme.d.ts +2 -0
- package/lib/typescript/api/theme/theme.d.ts.map +1 -1
- package/lib/typescript/engine/commands.d.ts +5 -0
- package/lib/typescript/engine/commands.d.ts.map +1 -1
- package/lib/typescript/engine/layout.d.ts.map +1 -1
- package/lib/typescript/engine/nativeScreens.d.ts +5 -0
- package/lib/typescript/engine/nativeScreens.d.ts.map +1 -1
- package/lib/typescript/engine/options.d.ts +5 -2
- package/lib/typescript/engine/options.d.ts.map +1 -1
- package/lib/typescript/engine/optionsChange.d.ts +28 -0
- package/lib/typescript/engine/optionsChange.d.ts.map +1 -0
- package/lib/typescript/engine/places.d.ts +7 -2
- package/lib/typescript/engine/places.d.ts.map +1 -1
- package/lib/typescript/engine/props.d.ts +8 -1
- package/lib/typescript/engine/props.d.ts.map +1 -1
- package/lib/typescript/engine/refresh.d.ts +35 -0
- package/lib/typescript/engine/refresh.d.ts.map +1 -0
- package/lib/typescript/engine/rememberedOptions.d.ts +13 -0
- package/lib/typescript/engine/rememberedOptions.d.ts.map +1 -1
- package/lib/typescript/engine/screens.d.ts +27 -6
- package/lib/typescript/engine/screens.d.ts.map +1 -1
- package/lib/typescript/interfaces/ComponentEvents.d.ts +4 -4
- package/lib/typescript/interfaces/ComponentEvents.d.ts.map +1 -1
- package/lib/typescript/interfaces/Events.d.ts +28 -10
- package/lib/typescript/interfaces/Events.d.ts.map +1 -1
- package/lib/typescript/interfaces/Options.d.ts +1 -1
- package/lib/typescript/interfaces/Options.d.ts.map +1 -1
- package/lib/typescript/interfaces/options/animations.d.ts +80 -22
- package/lib/typescript/interfaces/options/animations.d.ts.map +1 -1
- package/lib/typescript/interfaces/options/bottomTabs.d.ts +21 -7
- package/lib/typescript/interfaces/options/bottomTabs.d.ts.map +1 -1
- package/lib/typescript/interfaces/options/buttons.d.ts +23 -15
- package/lib/typescript/interfaces/options/buttons.d.ts.map +1 -1
- package/lib/typescript/interfaces/options/modals.d.ts +34 -26
- package/lib/typescript/interfaces/options/modals.d.ts.map +1 -1
- package/lib/typescript/interfaces/options/sideMenu.d.ts +23 -6
- package/lib/typescript/interfaces/options/sideMenu.d.ts.map +1 -1
- package/lib/typescript/interfaces/options/stack.d.ts +17 -3
- package/lib/typescript/interfaces/options/stack.d.ts.map +1 -1
- package/lib/typescript/interfaces/options/system.d.ts +18 -11
- package/lib/typescript/interfaces/options/system.d.ts.map +1 -1
- package/lib/typescript/interfaces/options/toolbar.d.ts +2 -2
- package/lib/typescript/interfaces/options/topBar.d.ts +68 -38
- package/lib/typescript/interfaces/options/topBar.d.ts.map +1 -1
- package/metro/acceptPlugin.js +57 -0
- package/metro/babelTransformer.js +45 -0
- package/metro/index.js +36 -0
- package/package.json +4 -25
- package/src/ARCHITECTURE.md +40 -27
- package/src/adapters/NativeANNTurboModule.ts +12 -2
- package/src/api/app/AppRegistry.ts +16 -2
- package/src/api/app/createNavigation.ts +203 -69
- package/src/api/commands/commands.ts +48 -7
- package/src/api/commands/presentation.ts +4 -3
- package/src/api/events/navigationEvents.ts +10 -4
- package/src/api/hooks/useNavigation.ts +9 -4
- package/src/api/hooks/useSafeAreaInsets.ts +4 -3
- package/src/api/index.ts +1 -0
- package/src/api/linking/dispatchedLinks.ts +18 -0
- package/src/api/linking/linking.ts +22 -1
- package/src/api/navigation.ts +4 -1
- package/src/api/options/OptionsChain.ts +2 -2
- package/src/api/screens/defineScreen.ts +49 -5
- package/src/api/screens/nativeScreens.ts +40 -4
- package/src/api/screens/registerScreens.tsx +185 -42
- package/src/api/theme/theme.ts +5 -0
- package/src/engine/commands.ts +70 -13
- package/src/engine/layout.ts +27 -11
- package/src/engine/nativeScreens.ts +10 -1
- package/src/engine/options.ts +45 -19
- package/src/engine/optionsChange.ts +107 -0
- package/src/engine/places.ts +65 -7
- package/src/engine/props.ts +30 -1
- package/src/engine/refresh.ts +97 -0
- package/src/engine/rememberedOptions.ts +74 -1
- package/src/engine/screens.tsx +76 -21
- package/src/interfaces/ComponentEvents.ts +4 -4
- package/src/interfaces/Events.ts +29 -10
- package/src/interfaces/Options.ts +1 -0
- package/src/interfaces/contract/commands.json +101 -0
- package/src/interfaces/contract/errors.json +275 -0
- package/src/interfaces/options/animations.ts +81 -22
- package/src/interfaces/options/bottomTabs.ts +21 -7
- package/src/interfaces/options/buttons.ts +23 -15
- package/src/interfaces/options/modals.ts +34 -26
- package/src/interfaces/options/sideMenu.ts +24 -6
- package/src/interfaces/options/stack.ts +17 -3
- package/src/interfaces/options/system.ts +18 -11
- package/src/interfaces/options/toolbar.ts +2 -2
- package/src/interfaces/options/topBar.ts +68 -38
- package/android/src/main/java/dev/apexnative/navigation/react/ArrangementStates.kt +0 -41
- package/android/src/main/java/dev/apexnative/navigation/react/ScreenInsets.kt +0 -69
- package/android/src/main/java/dev/apexnative/navigation/react/events/NavigationStateReporter.kt +0 -62
- package/android/src/main/java/dev/apexnative/navigation/react/events/StateHold.kt +0 -62
- package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/bottomtabs/CustomTabRowPlacer.kt +0 -223
- package/android/src/main/java/dev/apexnative/navigation/views/element/ElementStub.kt +0 -31
- package/android/src/main/java/dev/apexnative/navigation/views/element/animators/ImageMatrixAnimator.kt +0 -138
- package/android/src/main/java/dev/apexnative/navigation/views/element/animators/PlainViewAnimator.kt +0 -88
- package/android/src/main/java/dev/apexnative/navigation/views/element/animators/PropertyAnimatorCreator.kt +0 -33
- package/android/src/main/java/dev/apexnative/navigation/views/element/animators/ReactImageAnimator.kt +0 -66
- package/android/src/main/java/dev/apexnative/navigation/views/element/animators/TextChangeAnimator.kt +0 -179
- package/android/src/main/java/dev/apexnative/navigation/views/element/animators/ViewChangeAnimator.kt +0 -139
- package/ios/Layouts/Screen/ANNScreenInsets.h +0 -30
- package/ios/Layouts/Screen/ANNScreenInsets.mm +0 -68
- package/ios/Layouts/Tabs/ANNTabsPreloadWindow.h +0 -27
- package/ios/Layouts/Tabs/ANNTabsPreloadWindow.mm +0 -55
|
@@ -1,16 +1,8 @@
|
|
|
1
1
|
#import "ANNArrangementState.h"
|
|
2
2
|
#import "ANNArrangementViewController.h"
|
|
3
3
|
|
|
4
|
-
static NSMutableDictionary<NSString *, NSDictionary<NSString *, id> *> *ANNArrangementStateById;
|
|
5
|
-
|
|
6
4
|
@implementation ANNArrangementState
|
|
7
5
|
|
|
8
|
-
+ (void)initialize {
|
|
9
|
-
if (self == ANNArrangementState.class) {
|
|
10
|
-
ANNArrangementStateById = [NSMutableDictionary new];
|
|
11
|
-
}
|
|
12
|
-
}
|
|
13
|
-
|
|
14
6
|
+ (BOOL)canShowArrangements {
|
|
15
7
|
#if __IPHONE_OS_VERSION_MAX_ALLOWED >= 270100
|
|
16
8
|
if (@available(iOS 27.1, *)) {
|
|
@@ -20,34 +12,4 @@ static NSMutableDictionary<NSString *, NSDictionary<NSString *, id> *> *ANNArran
|
|
|
20
12
|
return NO;
|
|
21
13
|
}
|
|
22
14
|
|
|
23
|
-
+ (void)setState:(NSDictionary<NSString *, id> *)state
|
|
24
|
-
forScreenId:(NSString *)screenId
|
|
25
|
-
eventEmitter:(ANNEventEmitter *)eventEmitter {
|
|
26
|
-
@synchronized(ANNArrangementStateById) {
|
|
27
|
-
if ([ANNArrangementStateById[screenId] isEqualToDictionary:state]) {
|
|
28
|
-
return;
|
|
29
|
-
}
|
|
30
|
-
ANNArrangementStateById[screenId] = state;
|
|
31
|
-
}
|
|
32
|
-
[eventEmitter sendArrangementChanged:screenId state:state];
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
+ (NSDictionary<NSString *, id> *)stateForScreenId:(NSString *)screenId {
|
|
36
|
-
@synchronized(ANNArrangementStateById) {
|
|
37
|
-
return ANNArrangementStateById[screenId];
|
|
38
|
-
}
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
+ (void)removeScreenId:(NSString *)screenId {
|
|
42
|
-
@synchronized(ANNArrangementStateById) {
|
|
43
|
-
[ANNArrangementStateById removeObjectForKey:screenId];
|
|
44
|
-
}
|
|
45
|
-
}
|
|
46
|
-
|
|
47
|
-
+ (void)removeAll {
|
|
48
|
-
@synchronized(ANNArrangementStateById) {
|
|
49
|
-
[ANNArrangementStateById removeAllObjects];
|
|
50
|
-
}
|
|
51
|
-
}
|
|
52
|
-
|
|
53
15
|
@end
|
|
@@ -2,9 +2,10 @@
|
|
|
2
2
|
|
|
3
3
|
#if __IPHONE_OS_VERSION_MAX_ALLOWED >= 270100
|
|
4
4
|
|
|
5
|
-
#import "ANNArrangementState.h"
|
|
6
5
|
#import "ANNComponentViewController.h"
|
|
6
|
+
#import "ANNEventContract.h"
|
|
7
7
|
#import "ANNExternalViewController.h"
|
|
8
|
+
#import "ANNScreenEnvironment.h"
|
|
8
9
|
#import "ANNShownScreens.h"
|
|
9
10
|
#import "ANNUtils.h"
|
|
10
11
|
|
|
@@ -130,11 +131,12 @@ static BOOL ANNKeepsState(UIViewController *screen) {
|
|
|
130
131
|
|
|
131
132
|
static NSDictionary<NSString *, id> *ANNStateOf(NSString *placement, NSString *layout, BOOL front,
|
|
132
133
|
BOOL hidden) {
|
|
134
|
+
const auto &keys = ANNEventContract.ArrangementChanged;
|
|
133
135
|
return @{
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
136
|
+
keys.placement : placement,
|
|
137
|
+
keys.layout : layout,
|
|
138
|
+
keys.front : @(front),
|
|
139
|
+
keys.hidden : @(hidden),
|
|
138
140
|
};
|
|
139
141
|
}
|
|
140
142
|
|
|
@@ -296,9 +298,9 @@ static BOOL ANNIsShown(UIViewController *screen, UIArrangementViewState *state,
|
|
|
296
298
|
ofScreen:(UIViewController *)screen
|
|
297
299
|
eventEmitter:(ANNEventEmitter *)eventEmitter {
|
|
298
300
|
if (ANNKeepsState(screen)) {
|
|
299
|
-
[
|
|
300
|
-
|
|
301
|
-
|
|
301
|
+
[ANNScreenEnvironment setArrangement:state
|
|
302
|
+
forScreenId:screen.layoutInfo.componentId
|
|
303
|
+
eventEmitter:eventEmitter];
|
|
302
304
|
}
|
|
303
305
|
}
|
|
304
306
|
|
|
@@ -25,7 +25,7 @@ NS_ASSUME_NONNULL_BEGIN
|
|
|
25
25
|
|
|
26
26
|
/// `dismissModal`: the record of `componentId` (its root's id or any id inside, also of a modal closed below or by the
|
|
27
27
|
/// user), the options merged into its visible screen, the animation from the command's screen, then its state decides.
|
|
28
|
-
/// Answers with the root's id.
|
|
28
|
+
/// Answers with the root's id. The last modal over no root rejects `[ANNErrorTexts modalWithoutRoot:]`, as on Android.
|
|
29
29
|
+ (void)dismissModal:(NSString *)componentId
|
|
30
30
|
options:(nullable NSDictionary *)options
|
|
31
31
|
answer:(ANNCommandAnswer *)answer;
|
|
@@ -233,7 +233,7 @@ static void ANNCollectIds(UIViewController *node, NSMutableSet<NSString *> *ids)
|
|
|
233
233
|
limit:contentFirst ? 0 : ANNModalRenderLimit
|
|
234
234
|
bar:contentFirst ? ANNRenderWaitBarAfterContent : ANNRenderWaitBarWithContent
|
|
235
235
|
barLimits:contentFirst ? ownPhase : withContent];
|
|
236
|
-
wait.
|
|
236
|
+
wait.unseenLimit = ANNModalRenderLimit;
|
|
237
237
|
wait.protect = ^(dispatch_block_t step) {
|
|
238
238
|
[ANNModalCoordinator protect:weakModal step:step];
|
|
239
239
|
};
|
|
@@ -277,8 +277,8 @@ static void ANNCollectIds(UIViewController *node, NSMutableSet<NSString *> *ids)
|
|
|
277
277
|
|
|
278
278
|
// The end steps of a record (its show presented, its dismissal ended, closed by the user) run inside UIKit's
|
|
279
279
|
// completions and delegate calls, outside the runner's protection, in any state: a failure there is logged in one line,
|
|
280
|
-
//
|
|
281
|
-
// The gate's `done` ran before the step, as without a failure.
|
|
280
|
+
// answers what of the record still waits for an answer (its show, a chain step, its dismissals:
|
|
281
|
+
// `endFailedOf:showing:exception:`), and its drive stops. The gate's `done` ran before the step, as without a failure.
|
|
282
282
|
+ (void)protectEndOf:(ANNModal *)modal showing:(BOOL)showing step:(dispatch_block_t)step {
|
|
283
283
|
@try {
|
|
284
284
|
step();
|
|
@@ -288,24 +288,43 @@ static void ANNCollectIds(UIViewController *node, NSMutableSet<NSString *> *ids)
|
|
|
288
288
|
: (showing ? @"show a modal" : @"dismiss a modal");
|
|
289
289
|
NSString *reason = exception.reason.length > 0 ? exception.reason : exception.name;
|
|
290
290
|
RCTLogWarn(@"[ApexNavigation] %@", [ANNErrorTexts couldNot:what reason:reason]);
|
|
291
|
-
[self endFailedOf:modal exception:exception];
|
|
291
|
+
[self endFailedOf:modal showing:showing exception:exception];
|
|
292
292
|
}
|
|
293
293
|
}
|
|
294
294
|
|
|
295
|
-
|
|
295
|
+
// A failed end step of `modal`: its show rejects. After a failed show the dismissals that wait for it don't fail with
|
|
296
|
+
// it, as on Android: on a modal that shows they run now and resolve once it went (one still `Presenting` shows: UIKit's
|
|
297
|
+
// completion ran); on one that goes another way (a `dismissAllModals`, with the old root) or went already they resolve
|
|
298
|
+
// with its root's id; on one in another transition (a drag, its own dismissal) they wait for that transition's end.
|
|
299
|
+
// A failed dismissal rejects itself and the dismissals behind it.
|
|
300
|
+
+ (void)endFailedOf:(ANNModal *)modal showing:(BOOL)showing exception:(NSException *)exception {
|
|
296
301
|
if (!modal) {
|
|
297
302
|
return;
|
|
298
303
|
}
|
|
299
304
|
[self stopDriving:modal];
|
|
300
305
|
NSString *show = [NSString stringWithFormat:@"show the screen '%@'", modal.rootId];
|
|
301
|
-
NSString *dismiss = [NSString stringWithFormat:@"dismiss the modal '%@'", modal.rootId];
|
|
302
306
|
[modal.showAnswer reject:[ANNCommandRunner rejectionOf:exception what:show]];
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
307
|
+
ANNModalState state = modal.state;
|
|
308
|
+
BOOL goesAnotherWay = (state == ANNModalStateDismissing && modal.batch) ||
|
|
309
|
+
state == ANNModalStateWithOldRoot ||
|
|
310
|
+
state == ANNModalStateClosedBelow || state == ANNModalStateGone;
|
|
311
|
+
if (showing && state == ANNModalStatePresenting) {
|
|
312
|
+
modal.state = ANNModalStateShown;
|
|
313
|
+
}
|
|
314
|
+
if (showing && modal.state == ANNModalStateShown) {
|
|
315
|
+
[self runPendingOf:modal];
|
|
316
|
+
} else if (showing && goesAnotherWay) {
|
|
317
|
+
[modal.dismissal.answer resolve:modal.rootId];
|
|
318
|
+
[self resolvePendingOf:modal];
|
|
319
|
+
} else if (!showing) {
|
|
320
|
+
NSString *dismiss = [NSString stringWithFormat:@"dismiss the modal '%@'", modal.rootId];
|
|
321
|
+
NSString *dismissText = [ANNCommandRunner rejectionOf:exception what:dismiss];
|
|
322
|
+
[modal.dismissal.answer reject:dismissText];
|
|
323
|
+
NSArray<ANNModalDismissal *> *pending = modal.pending.copy;
|
|
324
|
+
[modal.pending removeAllObjects];
|
|
325
|
+
for (ANNModalDismissal *waiting in pending) {
|
|
326
|
+
[waiting.answer reject:dismissText];
|
|
327
|
+
}
|
|
309
328
|
}
|
|
310
329
|
// A `setRoot` chain goes on (its own steps are guarded by the root coordinator).
|
|
311
330
|
void (^chainStep)(BOOL) = modal.chainStep;
|
|
@@ -333,7 +352,7 @@ static void ANNCollectIds(UIViewController *node, NSMutableSet<NSString *> *ids)
|
|
|
333
352
|
[waiter reject:text];
|
|
334
353
|
}
|
|
335
354
|
for (ANNModal *modal in batch.records.copy) {
|
|
336
|
-
[self endFailedOf:modal exception:exception];
|
|
355
|
+
[self endFailedOf:modal showing:NO exception:exception];
|
|
337
356
|
}
|
|
338
357
|
}
|
|
339
358
|
}
|
|
@@ -407,7 +426,7 @@ static void ANNCollectIds(UIViewController *node, NSMutableSet<NSString *> *ids)
|
|
|
407
426
|
ANNNavigationOptions *resolved = [root resolveOptionsWithDefault];
|
|
408
427
|
ANNModalPresentation *presentation =
|
|
409
428
|
[[ANNModalPresentation alloc] initWithOptions:resolved animated:modal.animatedOverride];
|
|
410
|
-
NSString *problem = [presentation
|
|
429
|
+
NSString *problem = [presentation fitToPresenting:presenting windowRoot:windowRoot];
|
|
411
430
|
if (problem) {
|
|
412
431
|
[self failShowOf:modal reason:problem];
|
|
413
432
|
done();
|
|
@@ -537,7 +556,8 @@ static void ANNCollectIds(UIViewController *node, NSMutableSet<NSString *> *ids)
|
|
|
537
556
|
modal.coversUnder = under != nil && under.viewIfLoaded.window == nil;
|
|
538
557
|
NSArray<UIViewController *> *hidden = modal.coversUnder ? @[ under ] : @[];
|
|
539
558
|
@try {
|
|
540
|
-
// The chain step stays on the record until its events went: a failure there tells the chain
|
|
559
|
+
// The chain step stays on the record until its events went: a failure there tells the chain
|
|
560
|
+
// (`endFailedOf:showing:exception:`).
|
|
541
561
|
void (^chainStep)(BOOL) = modal.chainStep;
|
|
542
562
|
if (chainStep) {
|
|
543
563
|
[ANNAppearanceDispatcher endSwitchHiding:hidden showing:@[ root ] events:nil];
|
|
@@ -778,6 +798,11 @@ static void ANNCollectIds(UIViewController *node, NSMutableSet<NSString *> *ids)
|
|
|
778
798
|
[answer reject:[ANNErrorTexts screenNotShown:componentId]];
|
|
779
799
|
return;
|
|
780
800
|
}
|
|
801
|
+
// The last modal over no root (shown before any `setRoot`) stays: nothing would be left to show, as on Android.
|
|
802
|
+
if ([self isLastWithoutRoot:modal]) {
|
|
803
|
+
[answer reject:[ANNErrorTexts modalWithoutRoot:componentId]];
|
|
804
|
+
return;
|
|
805
|
+
}
|
|
781
806
|
// Step 1: the options, read on the main queue; one that can't be read rejects before anything changes. They merge
|
|
782
807
|
// into the modal's visible screen as `mergeOptions` would.
|
|
783
808
|
if (options.count > 0) {
|
|
@@ -815,6 +840,22 @@ static void ANNCollectIds(UIViewController *node, NSMutableSet<NSString *> *ids)
|
|
|
815
840
|
[self dismiss:modal with:dismissal];
|
|
816
841
|
}
|
|
817
842
|
|
|
843
|
+
// No root in the window (the splash, or nothing yet) and no other modal that shows or comes: `modal` is all a dismissal
|
|
844
|
+
// would take away. One closed below, going with the old root or gone takes nothing away, so it doesn't count.
|
|
845
|
+
+ (BOOL)isLastWithoutRoot:(ANNModal *)modal {
|
|
846
|
+
if (modal.state == ANNModalStateClosedBelow || modal.state == ANNModalStateGone ||
|
|
847
|
+
ApexNavigation.mainWindow.rootViewController.isLayoutNode) {
|
|
848
|
+
return NO;
|
|
849
|
+
}
|
|
850
|
+
for (ANNModal *other in ANNModals) {
|
|
851
|
+
if (other != modal && other.state != ANNModalStateClosedBelow &&
|
|
852
|
+
other.state != ANNModalStateWithOldRoot && other.state != ANNModalStateGone) {
|
|
853
|
+
return NO;
|
|
854
|
+
}
|
|
855
|
+
}
|
|
856
|
+
return YES;
|
|
857
|
+
}
|
|
858
|
+
|
|
818
859
|
// The modal of `node`: the record whose root is the top of `node`'s layout.
|
|
819
860
|
+ (ANNModal *)modalOf:(UIViewController *)node {
|
|
820
861
|
UIViewController *top = node;
|
|
@@ -897,7 +938,7 @@ static void ANNCollectIds(UIViewController *node, NSMutableSet<NSString *> *ids)
|
|
|
897
938
|
[ANNErrorTexts couldNot:what reason:exception.reason ?: exception.name]);
|
|
898
939
|
// The dismissal still open answers, and so do the dismissals waiting behind it (an answer given already
|
|
899
940
|
// stays as it was).
|
|
900
|
-
[self endFailedOf:modal exception:exception];
|
|
941
|
+
[self endFailedOf:modal showing:NO exception:exception];
|
|
901
942
|
done();
|
|
902
943
|
}
|
|
903
944
|
}
|
|
@@ -20,7 +20,8 @@ NS_ASSUME_NONNULL_BEGIN
|
|
|
20
20
|
|
|
21
21
|
/// `modalPresentationStyle`: one to one; unset is UIKit's automatic style; an unknown string full screen.
|
|
22
22
|
@property(nonatomic, readonly) UIModalPresentationStyle style;
|
|
23
|
-
/// `modalTransitionStyle`: `coverVertical` unless one of the others is given
|
|
23
|
+
/// `modalTransitionStyle`: `coverVertical` unless one of the others is given; `partialCurl` only where UIKit curls
|
|
24
|
+
/// (`fitToPresenting:windowRoot:`).
|
|
24
25
|
@property(nonatomic, readonly) UIModalTransitionStyle transitionStyle;
|
|
25
26
|
/// The present is animated: `enter.enabled` is not `false`.
|
|
26
27
|
@property(nonatomic, readonly) BOOL animated;
|
|
@@ -47,10 +48,12 @@ NS_ASSUME_NONNULL_BEGIN
|
|
|
47
48
|
animation:(nullable ANNModalAnimationOptions *)animation
|
|
48
49
|
under:(nullable UIViewController *)under;
|
|
49
50
|
|
|
50
|
-
///
|
|
51
|
-
///
|
|
52
|
-
|
|
53
|
-
|
|
51
|
+
/// Fits the show to `presenting`, before `prepare:…`: `partialCurl` stays only for a full-screen modal over a
|
|
52
|
+
/// controller that fills the screen (`presenting` is `windowRoot`, the main window's root, or a full-screen modal);
|
|
53
|
+
/// otherwise `transitionStyle` becomes `coverVertical`. Returns why UIKit can't make the show (`presenting` was shown
|
|
54
|
+
/// with `partialCurl`), as the reason of the rejection; nil when it can.
|
|
55
|
+
- (nullable NSString *)fitToPresenting:(UIViewController *)presenting
|
|
56
|
+
windowRoot:(nullable UIViewController *)windowRoot;
|
|
54
57
|
|
|
55
58
|
/// Before `presentViewController:`: the style and the transition, the presentation's delegate, the popover kept a
|
|
56
59
|
/// popover (`adaptive: false`), the sheet, the size, the popover's source on `presentingLayout`, the hold, the
|
|
@@ -118,21 +118,21 @@ static NSDictionary<NSString *, NSNumber *> *ANNTransitionStyles(void) {
|
|
|
118
118
|
return nil;
|
|
119
119
|
}
|
|
120
120
|
|
|
121
|
-
// UIKit
|
|
122
|
-
// shown with `partialCurl` presents nothing more: the command
|
|
123
|
-
|
|
124
|
-
|
|
121
|
+
// UIKit curls only a full-screen modal over a controller that fills the screen: elsewhere `partialCurl` is
|
|
122
|
+
// `coverVertical`, so the modal still shows. A controller shown with `partialCurl` presents nothing more: the command
|
|
123
|
+
// rejects before it asks UIKit.
|
|
124
|
+
- (NSString *)fitToPresenting:(UIViewController *)presenting
|
|
125
|
+
windowRoot:(UIViewController *)windowRoot {
|
|
125
126
|
if (presenting.presentingViewController &&
|
|
126
127
|
presenting.modalTransitionStyle == UIModalTransitionStylePartialCurl) {
|
|
127
|
-
return @"partialCurl
|
|
128
|
+
return @"a modal shown with partialCurl can't show another modal";
|
|
128
129
|
}
|
|
129
|
-
if (_transitionStyle
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
return @"partialCurl needs a full screen modal";
|
|
130
|
+
if (_transitionStyle == UIModalTransitionStylePartialCurl) {
|
|
131
|
+
BOOL presentingFills = presenting == windowRoot ||
|
|
132
|
+
presenting.modalPresentationStyle == UIModalPresentationFullScreen;
|
|
133
|
+
if (_style != UIModalPresentationFullScreen || !presentingFills) {
|
|
134
|
+
_transitionStyle = UIModalTransitionStyleCoverVertical;
|
|
135
|
+
}
|
|
136
136
|
}
|
|
137
137
|
return nil;
|
|
138
138
|
}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
#import "ANNSheetPresenter.h"
|
|
2
2
|
#import "ANNModalSizePresenter.h"
|
|
3
3
|
#import "ANNReactView.h"
|
|
4
|
+
#import "ANNUtils.h"
|
|
4
5
|
#import "UIViewController+LayoutProtocol.h"
|
|
5
6
|
#import <React/RCTLog.h>
|
|
6
7
|
#import <objc/runtime.h>
|
|
@@ -53,7 +54,7 @@ static NSString *const ANNContentDetent = @"content";
|
|
|
53
54
|
+ (void)applyOptions:(ANNSheetOptions *)options toSheet:(UISheetPresentationController *)sheet {
|
|
54
55
|
if (options.detents) {
|
|
55
56
|
NSMutableArray<UISheetPresentationControllerDetent *> *detents = [NSMutableArray new];
|
|
56
|
-
for (id value in options.detents) {
|
|
57
|
+
for (id value in [self sortedDetents:options.detents ofSheet:sheet]) {
|
|
57
58
|
UISheetPresentationControllerDetent *detent = [self detentFor:value ofSheet:sheet];
|
|
58
59
|
if (detent) {
|
|
59
60
|
[detents addObject:detent];
|
|
@@ -81,6 +82,85 @@ static NSString *const ANNContentDetent = @"content";
|
|
|
81
82
|
}
|
|
82
83
|
}
|
|
83
84
|
|
|
85
|
+
// UIKit wants the detents once each, from the lowest to the highest: it takes the last for the largest and closes the
|
|
86
|
+
// sheet on a drag down from the first. The options may give them in any order and more than once; the first of a
|
|
87
|
+
// repeat stays, and detents of the same height keep their order.
|
|
88
|
+
+ (NSArray *)sortedDetents:(NSArray *)values ofSheet:(UISheetPresentationController *)sheet {
|
|
89
|
+
NSMutableArray *detents = [NSMutableArray new];
|
|
90
|
+
NSMutableSet<NSString *> *identifiers = [NSMutableSet new];
|
|
91
|
+
for (id value in values) {
|
|
92
|
+
NSString *identifier = [self identifierFor:value];
|
|
93
|
+
if (identifier && ![identifiers containsObject:identifier]) {
|
|
94
|
+
[identifiers addObject:identifier];
|
|
95
|
+
[detents addObject:value];
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
CGFloat maximum = [self maximumDetentHeightOf:sheet];
|
|
99
|
+
return [detents sortedArrayWithOptions:NSSortStable
|
|
100
|
+
usingComparator:^NSComparisonResult(id a, id b) {
|
|
101
|
+
return [self compareHeightOf:a
|
|
102
|
+
with:b
|
|
103
|
+
maximum:maximum
|
|
104
|
+
ofSheet:sheet];
|
|
105
|
+
}];
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
// The content of a sheet sized to it changed its height, and with it maybe its place among the other detents.
|
|
109
|
+
+ (void)sortDetentsOfSheet:(UISheetPresentationController *)sheet API_AVAILABLE(ios(16.0)) {
|
|
110
|
+
CGFloat maximum = [self maximumDetentHeightOf:sheet];
|
|
111
|
+
NSArray<UISheetPresentationControllerDetent *> *detents = sheet.detents;
|
|
112
|
+
NSArray<UISheetPresentationControllerDetent *> *sorted = [detents
|
|
113
|
+
sortedArrayWithOptions:NSSortStable
|
|
114
|
+
usingComparator:^NSComparisonResult(UISheetPresentationControllerDetent *a,
|
|
115
|
+
UISheetPresentationControllerDetent *b) {
|
|
116
|
+
return [self compareHeightOf:[self detentForIdentifier:a.identifier]
|
|
117
|
+
with:[self detentForIdentifier:b.identifier]
|
|
118
|
+
maximum:maximum
|
|
119
|
+
ofSheet:sheet];
|
|
120
|
+
}];
|
|
121
|
+
if (![sorted isEqualToArray:detents]) {
|
|
122
|
+
sheet.detents = sorted;
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
+ (NSComparisonResult)compareHeightOf:(id)a
|
|
127
|
+
with:(id)b
|
|
128
|
+
maximum:(CGFloat)maximum
|
|
129
|
+
ofSheet:(UISheetPresentationController *)sheet {
|
|
130
|
+
CGFloat heightA = [self heightOf:a maximum:maximum ofSheet:sheet];
|
|
131
|
+
CGFloat heightB = [self heightOf:b maximum:maximum ofSheet:sheet];
|
|
132
|
+
return heightA < heightB ? NSOrderedAscending
|
|
133
|
+
: heightA > heightB ? NSOrderedDescending : NSOrderedSame;
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
// The height a detent of the options stands at, to sort them, as its resolver gives it: 'medium' half of the largest
|
|
137
|
+
// height (UIKit's is about half), 'large' all of it, a height capped at it, 'content' the content's height now, all of
|
|
138
|
+
// it while the content isn't measured.
|
|
139
|
+
+ (CGFloat)heightOf:(id)value
|
|
140
|
+
maximum:(CGFloat)maximum
|
|
141
|
+
ofSheet:(UISheetPresentationController *)sheet {
|
|
142
|
+
if ([value isEqual:@"medium"]) {
|
|
143
|
+
return maximum / 2;
|
|
144
|
+
}
|
|
145
|
+
if ([value isKindOfClass:NSNumber.class]) {
|
|
146
|
+
return MIN([value doubleValue], maximum);
|
|
147
|
+
}
|
|
148
|
+
if ([value isEqual:ANNContentDetent]) {
|
|
149
|
+
CGFloat height = [self contentHeightOf:sheet.presentedViewController];
|
|
150
|
+
return height > 0 ? MIN(height, maximum) : maximum;
|
|
151
|
+
}
|
|
152
|
+
return maximum;
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
// About the largest height of a sheet: its container, or the window before it is shown, below the top safe area.
|
|
156
|
+
+ (CGFloat)maximumDetentHeightOf:(UISheetPresentationController *)sheet {
|
|
157
|
+
UIView *view = sheet.containerView ?: ANNUtils.mainWindow;
|
|
158
|
+
if (!view) {
|
|
159
|
+
return ANNUtils.mainScreen.bounds.size.height;
|
|
160
|
+
}
|
|
161
|
+
return view.bounds.size.height - view.safeAreaInsets.top;
|
|
162
|
+
}
|
|
163
|
+
|
|
84
164
|
+ (UISheetPresentationControllerDetent *)detentFor:(id)value
|
|
85
165
|
ofSheet:(UISheetPresentationController *)sheet {
|
|
86
166
|
if ([value isEqual:@"medium"]) {
|
|
@@ -180,6 +260,7 @@ static NSString *const ANNContentDetent = @"content";
|
|
|
180
260
|
}
|
|
181
261
|
height = newHeight;
|
|
182
262
|
[strongSheet animateChanges:^{
|
|
263
|
+
[self sortDetentsOfSheet:strongSheet];
|
|
183
264
|
[strongSheet invalidateDetents];
|
|
184
265
|
}];
|
|
185
266
|
}
|
|
@@ -201,6 +282,7 @@ static NSString *const ANNContentDetent = @"content";
|
|
|
201
282
|
// The new screen's content mounts may come later: its mounts resolve the detents again too.
|
|
202
283
|
[self followContentOfSheet:sheet when:YES];
|
|
203
284
|
[sheet animateChanges:^{
|
|
285
|
+
[self sortDetentsOfSheet:sheet];
|
|
204
286
|
[sheet invalidateDetents];
|
|
205
287
|
}];
|
|
206
288
|
}
|
|
@@ -179,7 +179,7 @@ static NSMutableArray<ANNOverlay *> *ANNOverlays;
|
|
|
179
179
|
limit:ANNOverlayRenderLimit
|
|
180
180
|
bar:ANNRenderWaitBarWithContent
|
|
181
181
|
barLimits:withContent];
|
|
182
|
-
wait.
|
|
182
|
+
wait.unseenLimit = ANNOverlayRenderLimit;
|
|
183
183
|
wait.protect = ^(dispatch_block_t step) {
|
|
184
184
|
[ANNOverlayCoordinator protectWaitOf:weakOverlay step:step];
|
|
185
185
|
};
|
|
@@ -238,13 +238,7 @@ static NSMutableArray<ANNOverlay *> *ANNOverlays;
|
|
|
238
238
|
[self dismiss:shown answer:nil];
|
|
239
239
|
}
|
|
240
240
|
}
|
|
241
|
-
|
|
242
|
-
UIWindowScene *scene = mainWindow.windowScene;
|
|
243
|
-
// `initWithFrame:` is deprecated from iOS 26 on and warns only with a deployment target from 26: a window
|
|
244
|
-
// without a scene is made so, and joins the scene as the main window gets it.
|
|
245
|
-
ANNOverlayWindow *window =
|
|
246
|
-
scene ? [[ANNOverlayWindow alloc] initWithWindowScene:scene]
|
|
247
|
-
: [[ANNOverlayWindow alloc] initWithFrame:ANNUtils.mainScreen.bounds];
|
|
241
|
+
ANNOverlayWindow *window = [ANNUtils makeWindowOfClass:ANNOverlayWindow.class];
|
|
248
242
|
window.windowLevel = UIWindowLevelNormal;
|
|
249
243
|
window.backgroundColor = UIColor.clearColor;
|
|
250
244
|
window.previousWindow = [self keyWindow];
|
|
@@ -69,7 +69,10 @@ typedef NS_ENUM(NSInteger, ANNRootShowState) {
|
|
|
69
69
|
// The nodes whose appearance the transition reports itself (`driveAppearanceOf:`), while `driving`.
|
|
70
70
|
@property(nonatomic, copy) NSArray<UIViewController *> *driven;
|
|
71
71
|
@property(nonatomic) BOOL driving;
|
|
72
|
+
// The snapshot of the window as it was: it dissolves over the new root (`dissolves`), plays its `exit` (`custom`), or
|
|
73
|
+
// only covers the old root's modals while they go, and leaves as the new root is the window's.
|
|
72
74
|
@property(nonatomic, strong, nullable) UIView *snapshot;
|
|
75
|
+
@property(nonatomic) BOOL dissolves;
|
|
73
76
|
// The root is the window's root: the old root's modals went before it (`startTransitionOf:done:`).
|
|
74
77
|
@property(nonatomic) BOOL installed;
|
|
75
78
|
// The root's view waits in the window under the current root (`park:`).
|
|
@@ -80,6 +83,10 @@ typedef NS_ENUM(NSInteger, ANNRootShowState) {
|
|
|
80
83
|
@property(nonatomic, strong, nullable) ANNFrameDriver *driver;
|
|
81
84
|
@property(nonatomic, copy, nullable) NSArray<ANNViewTracks *> *tracks;
|
|
82
85
|
@property(nonatomic) BOOL animating;
|
|
86
|
+
// The new root's view takes no touches while it animates, and whether it took them before: Core Animation draws it
|
|
87
|
+
// elsewhere than where it is (the view itself stays in place), so a tap on the old screen would reach it.
|
|
88
|
+
@property(nonatomic, weak, nullable) UIView *untouchableRoot;
|
|
89
|
+
@property(nonatomic) BOOL rootTouchesBefore;
|
|
83
90
|
@property(nonatomic) BOOL layersShown;
|
|
84
91
|
@end
|
|
85
92
|
|
|
@@ -293,7 +300,7 @@ static __weak ANNRootShow *ANNAnimatingShow;
|
|
|
293
300
|
barLimits:contentFirst ? ownPhase : withContent];
|
|
294
301
|
// A screen the user won't see at once (an unselected tab's) never holds the root longer than the limit, also with
|
|
295
302
|
// `waitForRender: true`.
|
|
296
|
-
wait.
|
|
303
|
+
wait.unseenLimit = ANNRootRenderLimit;
|
|
297
304
|
wait.protect = ^(dispatch_block_t step) {
|
|
298
305
|
[ANNRootCoordinator protect:weakShow step:step];
|
|
299
306
|
};
|
|
@@ -415,9 +422,14 @@ static __weak ANNRootShow *ANNAnimatingShow;
|
|
|
415
422
|
BOOL seen = !window.hidden && scene != nil &&
|
|
416
423
|
scene.activationState != UISceneActivationStateBackground;
|
|
417
424
|
BOOL dissolves = !overSplash && !enterDisabled && !custom && seen;
|
|
425
|
+
show.dissolves = dissolves;
|
|
418
426
|
show.custom = custom && seen;
|
|
419
|
-
|
|
420
|
-
|
|
427
|
+
// UIKit draws the dismissal of the old root's modals, without animation too (a sheet's dim goes a frame before
|
|
428
|
+
// its card): with nothing to dissolve, the snapshot covers them until the new root is in place.
|
|
429
|
+
BOOL covers = seen && old.presentedViewController != nil;
|
|
430
|
+
UIView *snapshot = dissolves || show.custom || covers
|
|
431
|
+
? [window snapshotViewAfterScreenUpdates:NO]
|
|
432
|
+
: nil;
|
|
421
433
|
|
|
422
434
|
show.state = ANNRootShowStateTransition;
|
|
423
435
|
// It shows from here: a stack in it counts as on screen.
|
|
@@ -480,7 +492,8 @@ static __weak ANNRootShow *ANNAnimatingShow;
|
|
|
480
492
|
[self endTransitionOf:show];
|
|
481
493
|
return;
|
|
482
494
|
}
|
|
483
|
-
|
|
495
|
+
// A snapshot that only covered the old root's modals leaves in this turn, with the new root in place under it.
|
|
496
|
+
if (!snapshot || !show.dissolves) {
|
|
484
497
|
[self endTransitionOf:show];
|
|
485
498
|
return;
|
|
486
499
|
}
|
|
@@ -524,20 +537,43 @@ static __weak ANNRootShow *ANNAnimatingShow;
|
|
|
524
537
|
NSMutableArray<ANNViewTracks *> *tracks = [NSMutableArray new];
|
|
525
538
|
ANNViewAnimationOptions *enter = [ANNAnimationRules playingSide:animation.enter];
|
|
526
539
|
ANNViewAnimationOptions *exit = [ANNAnimationRules playingSide:animation.exit];
|
|
527
|
-
if (enter && rootView) {
|
|
528
|
-
[tracks addObject:[[ANNViewTracks alloc] initWithView:rootView
|
|
529
|
-
side:enter
|
|
530
|
-
alphaBefore:rootView.alpha]];
|
|
531
|
-
}
|
|
532
|
-
if (exit && snapshot) {
|
|
533
|
-
[tracks addObject:[[ANNViewTracks alloc] initWithView:snapshot
|
|
534
|
-
side:exit
|
|
535
|
-
alphaBefore:snapshot.alpha]];
|
|
536
|
-
}
|
|
537
540
|
NSTimeInterval length =
|
|
538
541
|
MAX([ANNAnimationRules lengthOfSide:enter], [ANNAnimationRules lengthOfSide:exit]);
|
|
542
|
+
if (UIAccessibilityIsReduceMotionEnabled() && length > 0) {
|
|
543
|
+
// With the system's Reduce Motion on, nothing moves: the new root fades in over the snapshot in the same
|
|
544
|
+
// length, or the snapshot fades out without a new root's view.
|
|
545
|
+
if (rootView) {
|
|
546
|
+
[tracks addObject:[[ANNViewTracks alloc] initWithView:rootView
|
|
547
|
+
fadeFrom:0
|
|
548
|
+
to:rootView.alpha
|
|
549
|
+
duration:length
|
|
550
|
+
alphaBefore:rootView.alpha]];
|
|
551
|
+
} else if (snapshot) {
|
|
552
|
+
[tracks addObject:[[ANNViewTracks alloc] initWithView:snapshot
|
|
553
|
+
fadeFrom:snapshot.alpha
|
|
554
|
+
to:0
|
|
555
|
+
duration:length
|
|
556
|
+
alphaBefore:snapshot.alpha]];
|
|
557
|
+
}
|
|
558
|
+
} else {
|
|
559
|
+
if (enter && rootView) {
|
|
560
|
+
[tracks addObject:[[ANNViewTracks alloc] initWithView:rootView
|
|
561
|
+
side:enter
|
|
562
|
+
alphaBefore:rootView.alpha]];
|
|
563
|
+
}
|
|
564
|
+
if (exit && snapshot) {
|
|
565
|
+
[tracks addObject:[[ANNViewTracks alloc] initWithView:snapshot
|
|
566
|
+
side:exit
|
|
567
|
+
alphaBefore:snapshot.alpha]];
|
|
568
|
+
}
|
|
569
|
+
}
|
|
539
570
|
show.tracks = tracks;
|
|
540
571
|
show.animating = YES;
|
|
572
|
+
if (rootView) {
|
|
573
|
+
show.untouchableRoot = rootView;
|
|
574
|
+
show.rootTouchesBefore = rootView.userInteractionEnabled;
|
|
575
|
+
rootView.userInteractionEnabled = NO;
|
|
576
|
+
}
|
|
541
577
|
ANNAnimatingShow = show;
|
|
542
578
|
show.driver = [[ANNFrameDriver alloc] initWithClients:tracks length:length];
|
|
543
579
|
// The layers' state from here on: the chain may start and a newer `setRoot` stops it.
|
|
@@ -574,8 +610,8 @@ static __weak ANNRootShow *ANNAnimatingShow;
|
|
|
574
610
|
[self finishLayersOf:show];
|
|
575
611
|
}
|
|
576
612
|
|
|
577
|
-
// The animation stops
|
|
578
|
-
// had and the snapshot goes.
|
|
613
|
+
// The animation stops (its end, a newer `setRoot`, a reload, a failure): its animations go, the views get back what
|
|
614
|
+
// they had and the snapshot goes.
|
|
579
615
|
+ (void)stopAnimationOf:(ANNRootShow *)show {
|
|
580
616
|
if (!show.animating) {
|
|
581
617
|
return;
|
|
@@ -583,13 +619,16 @@ static __weak ANNRootShow *ANNAnimatingShow;
|
|
|
583
619
|
show.animating = NO;
|
|
584
620
|
[show.driver cancel];
|
|
585
621
|
show.driver = nil;
|
|
622
|
+
show.untouchableRoot.userInteractionEnabled = show.rootTouchesBefore;
|
|
623
|
+
show.untouchableRoot = nil;
|
|
586
624
|
for (ANNViewTracks *tracks in show.tracks) {
|
|
587
625
|
[tracks restore];
|
|
588
626
|
}
|
|
589
627
|
show.tracks = nil;
|
|
590
|
-
// UIKit works out the safe area of the window's root view from where the view is
|
|
591
|
-
//
|
|
592
|
-
//
|
|
628
|
+
// UIKit works out the safe area of the window's root view from where the view is: moved away from the top edge by
|
|
629
|
+
// a transform it has no top inset, and putting the transform back doesn't make UIKit work it out again. `enter`
|
|
630
|
+
// moves only what Core Animation draws now; the layout stays, so the root, its bars and its screens end with the
|
|
631
|
+
// window's safe area whatever moved them.
|
|
593
632
|
UIView *rootView = show.root.viewIfLoaded;
|
|
594
633
|
[rootView setNeedsLayout];
|
|
595
634
|
[rootView layoutIfNeeded];
|
|
@@ -7,9 +7,11 @@ NS_ASSUME_NONNULL_BEGIN
|
|
|
7
7
|
/// either at once. The status bar follows the Info.plist keys `UIStatusBarStyle` and `UIStatusBarHidden`. Main queue.
|
|
8
8
|
@interface ANNSplashViewController : UIViewController
|
|
9
9
|
|
|
10
|
-
/// The copy of the launch screen
|
|
11
|
-
///
|
|
12
|
-
///
|
|
10
|
+
/// The copy of the launch screen. When iOS builds it from the Info.plist (`UILaunchScreen`, or the default of
|
|
11
|
+
/// `UILaunchScreens`), the same color, image and bars as plain views; else the initial view controller of
|
|
12
|
+
/// `UILaunchStoryboardName` as a child (a storyboard that doesn't load: the first view of the nib of that name), else
|
|
13
|
+
/// the legacy launch images, full screen. Nil when the app has none of these: the window then has no root view
|
|
14
|
+
/// controller until the first root.
|
|
13
15
|
+ (nullable instancetype)launchScreenCopyWithBounds:(CGRect)bounds;
|
|
14
16
|
|
|
15
17
|
/// The blank screen after a reload: clear when the default options give the window a color (`window.backgroundColor`),
|