@apexnative/navigation 1.0.0-alpha.1 → 1.0.0-alpha.11
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 +132 -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/ArrangementDefinition.kt +9 -3
- package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/arrangement/ArrangementPlanner.kt +20 -15
- 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/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/arrangement.md +17 -1
- 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 +61 -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 +195 -21
- 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 +34 -0
- package/ios/Layouts/Screen/ANNScreenSettling.mm +171 -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/arrangement.js +5 -2
- package/lib/module/api/screens/arrangement.js.map +1 -1
- 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/arrangement.d.ts +12 -2
- package/lib/typescript/api/screens/arrangement.d.ts.map +1 -1
- 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 +3 -1
- 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/arrangement.ts +17 -4
- 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
|
|
|
@@ -47,6 +48,14 @@ static NSDirectionalRectEdge ANNOppositeEdge(NSDirectionalRectEdge edge) {
|
|
|
47
48
|
}
|
|
48
49
|
}
|
|
49
50
|
|
|
51
|
+
// `primaryEdge` of a split: whether the primary goes second, at the trailing side or at the bottom. A split has no edge
|
|
52
|
+
// of its own: UIKit puts the view of its primary placement first along either axis (measured on iPhone Duo), so the
|
|
53
|
+
// edge decides which screen goes into that placement.
|
|
54
|
+
static BOOL ANNSecondaryFirst(NSDictionary *data) {
|
|
55
|
+
return ![@"overlay" isEqual:data[@"style"]] &&
|
|
56
|
+
([@"trailing" isEqual:data[@"primaryEdge"]] || [@"bottom" isEqual:data[@"primaryEdge"]]);
|
|
57
|
+
}
|
|
58
|
+
|
|
50
59
|
// Overlay view properties with the edge a view takes when the pair goes side by side.
|
|
51
60
|
static UIOverlayArrangementViewProperties *ANNOverlayProperties(UIOverlayArrangement *overlay,
|
|
52
61
|
NSDirectionalRectEdge edge)
|
|
@@ -94,8 +103,11 @@ static UIArrangement *ANNArrangementOfData(NSDictionary *data) API_AVAILABLE(ios
|
|
|
94
103
|
height.preferred = dimension;
|
|
95
104
|
primary.height = height;
|
|
96
105
|
}
|
|
97
|
-
|
|
98
|
-
|
|
106
|
+
// The share is the primary screen's, in whichever placement it is.
|
|
107
|
+
UIArrangementViewControllerViewPlacement placement =
|
|
108
|
+
ANNSecondaryFirst(data) ? UIArrangementViewControllerViewPlacementSecondary
|
|
109
|
+
: UIArrangementViewControllerViewPlacementPrimary;
|
|
110
|
+
[split setViewProperties:primary forPlacement:placement];
|
|
99
111
|
}
|
|
100
112
|
return split;
|
|
101
113
|
}
|
|
@@ -108,6 +120,38 @@ static UIArrangement *ANNPrimaryAloneArrangement(void) API_AVAILABLE(ios(27.1))
|
|
|
108
120
|
return split;
|
|
109
121
|
}
|
|
110
122
|
|
|
123
|
+
// A size range from `minimum` to `maximum`, preferring `preferred`.
|
|
124
|
+
static UISplitArrangementDimensionRange *ANNDimensionRange(UISplitArrangementDimension *minimum,
|
|
125
|
+
UISplitArrangementDimension *preferred,
|
|
126
|
+
UISplitArrangementDimension *maximum)
|
|
127
|
+
API_AVAILABLE(ios(27.1)) {
|
|
128
|
+
UISplitArrangementDimensionRange *range = [UISplitArrangementDimensionRange new];
|
|
129
|
+
range.minimum = minimum;
|
|
130
|
+
range.preferred = preferred;
|
|
131
|
+
range.maximum = maximum;
|
|
132
|
+
return range;
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
// The primary alone in the secondary placement, with the primary placement empty. UIKit keeps the empty placement's
|
|
136
|
+
// share of a split (measured on iPhone Duo folded: the primary in the lower half, the upper one blank), so the empty
|
|
137
|
+
// placement gets no room and the primary all of it, along either axis, which no shape of the window leaves out.
|
|
138
|
+
static UIArrangement *ANNSecondPlacementAloneArrangement(void) API_AVAILABLE(ios(27.1)) {
|
|
139
|
+
UISplitArrangement *split = [UISplitArrangement splitArrangement];
|
|
140
|
+
split.axes = UIAxisHorizontal | UIAxisVertical;
|
|
141
|
+
UISplitArrangementDimension *none = [UISplitArrangementDimension absoluteDimension:0];
|
|
142
|
+
UISplitArrangementDimension *all = [UISplitArrangementDimension fractionalDimension:1];
|
|
143
|
+
UISplitArrangementViewProperties *empty = [split.defaultViewProperties copy];
|
|
144
|
+
empty.width = ANNDimensionRange(none, none, none);
|
|
145
|
+
empty.height = ANNDimensionRange(none, none, none);
|
|
146
|
+
[split setViewProperties:empty forPlacement:UIArrangementViewControllerViewPlacementPrimary];
|
|
147
|
+
UISplitArrangementViewProperties *primary = [split.defaultViewProperties copy];
|
|
148
|
+
primary.width = ANNDimensionRange(all, all, all);
|
|
149
|
+
primary.height = ANNDimensionRange(all, all, all);
|
|
150
|
+
[split setViewProperties:primary
|
|
151
|
+
forPlacement:UIArrangementViewControllerViewPlacementSecondary];
|
|
152
|
+
return split;
|
|
153
|
+
}
|
|
154
|
+
|
|
111
155
|
// Room for a pair: both size classes regular (iPad, iPhone Duo unfolded). Nil without a size class yet: the view
|
|
112
156
|
// controller is not in a window.
|
|
113
157
|
static NSNumber *ANNIsLargeWindow(UITraitCollection *traits) {
|
|
@@ -130,11 +174,12 @@ static BOOL ANNKeepsState(UIViewController *screen) {
|
|
|
130
174
|
|
|
131
175
|
static NSDictionary<NSString *, id> *ANNStateOf(NSString *placement, NSString *layout, BOOL front,
|
|
132
176
|
BOOL hidden) {
|
|
177
|
+
const auto &keys = ANNEventContract.ArrangementChanged;
|
|
133
178
|
return @{
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
179
|
+
keys.placement : placement,
|
|
180
|
+
keys.layout : layout,
|
|
181
|
+
keys.front : @(front),
|
|
182
|
+
keys.hidden : @(hidden),
|
|
138
183
|
};
|
|
139
184
|
}
|
|
140
185
|
|
|
@@ -181,9 +226,20 @@ static BOOL ANNIsShown(UIViewController *screen, UIArrangementViewState *state,
|
|
|
181
226
|
// (`compact: 'primary'`).
|
|
182
227
|
UIArrangement *_arrangement;
|
|
183
228
|
BOOL _primaryAloneWhenSmall;
|
|
229
|
+
// `primaryEdge` of a split at the trailing side or the bottom: the secondary is in UIKit's primary placement, the
|
|
230
|
+
// primary in its secondary one. The primary alone keeps its placement and the secondary leaves its own, so the
|
|
231
|
+
// primary never changes its container at a fold. The axes the pair may use, for the primary alone then.
|
|
232
|
+
BOOL _secondaryFirst;
|
|
233
|
+
UIAxis _axes;
|
|
234
|
+
// The size a running size transition leads to, zero without one: the shape the pair decides its axes by.
|
|
235
|
+
CGSize _transitionSize;
|
|
184
236
|
// What UIKit has now, once an arrangement went to it.
|
|
185
237
|
BOOL _arranged;
|
|
186
238
|
BOOL _primaryAlone;
|
|
239
|
+
// The scene's size classes the pair takes for a size transition, and which transition set them last: only that
|
|
240
|
+
// one's end takes them away.
|
|
241
|
+
BOOL _sceneSizeClasses;
|
|
242
|
+
NSUInteger _sceneSizeClassesTransition;
|
|
187
243
|
}
|
|
188
244
|
|
|
189
245
|
- (instancetype)initWithLayoutInfo:(ANNLayoutInfo *)layoutInfo
|
|
@@ -216,14 +272,16 @@ static BOOL ANNIsShown(UIViewController *screen, UIArrangementViewState *state,
|
|
|
216
272
|
((ANNComponentViewController *)screen).arrangement = self;
|
|
217
273
|
}
|
|
218
274
|
}
|
|
219
|
-
|
|
275
|
+
_secondaryFirst = ANNSecondaryFirst(data);
|
|
276
|
+
_axes = ANNArrangementAxes(data[@"axes"]);
|
|
277
|
+
[self setViewController:_secondaryFirst ? secondary : primary
|
|
220
278
|
forPlacement:UIArrangementViewControllerViewPlacementPrimary];
|
|
221
|
-
[self setViewController:secondary
|
|
279
|
+
[self setViewController:_secondaryFirst ? primary : secondary
|
|
222
280
|
forPlacement:UIArrangementViewControllerViewPlacementSecondary];
|
|
223
281
|
_arrangement = ANNArrangementOfData(data);
|
|
224
282
|
_primaryAloneWhenSmall = ![@"pair" isEqual:data[@"compact"]];
|
|
225
283
|
// Before it is in a window: the window's size classes, which it will most likely have.
|
|
226
|
-
[self arrangeForTraits:ANNUtils.mainWindow.traitCollection
|
|
284
|
+
[self arrangeForTraits:ANNUtils.mainWindow.traitCollection];
|
|
227
285
|
if (!_arranged) {
|
|
228
286
|
[self updateArrangement:_arrangement animated:NO];
|
|
229
287
|
}
|
|
@@ -237,19 +295,33 @@ static BOOL ANNIsShown(UIViewController *screen, UIArrangementViewState *state,
|
|
|
237
295
|
// `compact: 'primary'`: the pair shows only in a large window; in any other (an iPhone, iPhone Duo folded) the primary
|
|
238
296
|
// shows alone, and the secondary waits out of the window until the window is large (iPhone Duo unfolded). With
|
|
239
297
|
// `compact: 'pair'` UIKit lays the pair out everywhere.
|
|
240
|
-
- (void)arrangeForTraits:(UITraitCollection *)traits
|
|
298
|
+
- (void)arrangeForTraits:(UITraitCollection *)traits {
|
|
241
299
|
NSNumber *large = ANNIsLargeWindow(traits);
|
|
242
300
|
if (!large) {
|
|
243
301
|
return;
|
|
244
302
|
}
|
|
245
|
-
BOOL alone = _primaryAloneWhenSmall && !large.boolValue
|
|
303
|
+
BOOL alone = (_primaryAloneWhenSmall && !large.boolValue) ||
|
|
304
|
+
(_secondaryFirst && ![self axesAllowSize:[self pairSize]]);
|
|
246
305
|
if (_arranged && alone == _primaryAlone) {
|
|
247
306
|
return;
|
|
248
307
|
}
|
|
249
308
|
BOOL changed = _arranged;
|
|
250
309
|
_arranged = YES;
|
|
251
310
|
_primaryAlone = alone;
|
|
252
|
-
|
|
311
|
+
if (_secondaryFirst) {
|
|
312
|
+
// The secondary leaves the window with its placement, as a split with no axis takes it out otherwise.
|
|
313
|
+
UIViewController *first = alone ? nil : _secondary;
|
|
314
|
+
if ([self viewControllerForPlacement:UIArrangementViewControllerViewPlacementPrimary] !=
|
|
315
|
+
first) {
|
|
316
|
+
[self setViewController:first
|
|
317
|
+
forPlacement:UIArrangementViewControllerViewPlacementPrimary
|
|
318
|
+
animated:NO];
|
|
319
|
+
}
|
|
320
|
+
[self updateArrangement:alone ? ANNSecondPlacementAloneArrangement() : _arrangement
|
|
321
|
+
animated:NO];
|
|
322
|
+
} else {
|
|
323
|
+
[self updateArrangement:alone ? ANNPrimaryAloneArrangement() : _arrangement animated:NO];
|
|
324
|
+
}
|
|
253
325
|
// A secondary that leaves the window renders no content: the pair waits for it no more.
|
|
254
326
|
if (alone && _secondaryCounted) {
|
|
255
327
|
_secondaryCounted = NO;
|
|
@@ -262,8 +334,103 @@ static BOOL ANNIsShown(UIViewController *screen, UIArrangementViewState *state,
|
|
|
262
334
|
}
|
|
263
335
|
}
|
|
264
336
|
|
|
337
|
+
// Where the axes leave the pair no room, UIKit shows its primary placement alone: with the secondary first that would
|
|
338
|
+
// be the secondary, so the pair takes it out itself, by the shape UIKit goes by (side by side in a wide window, one
|
|
339
|
+
// above the other in a tall one, measured on iPhone Duo).
|
|
340
|
+
- (BOOL)axesAllowSize:(CGSize)size {
|
|
341
|
+
if ((_axes & UIAxisHorizontal) && (_axes & UIAxisVertical)) {
|
|
342
|
+
return YES;
|
|
343
|
+
}
|
|
344
|
+
BOOL wide = size.width > size.height;
|
|
345
|
+
return (_axes & (wide ? UIAxisHorizontal : UIAxisVertical)) != 0;
|
|
346
|
+
}
|
|
347
|
+
|
|
348
|
+
// The pair's size: where a size transition leads, its own once laid out, the window's before.
|
|
349
|
+
- (CGSize)pairSize {
|
|
350
|
+
if (!CGSizeEqualToSize(_transitionSize, CGSizeZero)) {
|
|
351
|
+
return _transitionSize;
|
|
352
|
+
}
|
|
353
|
+
CGSize size = self.viewIfLoaded.bounds.size;
|
|
354
|
+
return size.width > 0 && size.height > 0 ? size : ANNUtils.mainWindow.bounds.size;
|
|
355
|
+
}
|
|
356
|
+
|
|
357
|
+
// New size classes come with a new window size, which leads the pair to its new place. UIKit's own animation of the
|
|
358
|
+
// arrangement would aim at a layout it gives only in between (on iPhone Duo, one above the other while the window
|
|
359
|
+
// still has its old size classes) and play on after the pair took its real one: the screens lagged by half a second.
|
|
265
360
|
- (void)sizeClassesDidChange {
|
|
266
|
-
[self arrangeForTraits:self.traitCollection
|
|
361
|
+
[self arrangeForTraits:self.traitCollection];
|
|
362
|
+
}
|
|
363
|
+
|
|
364
|
+
// On iPhone Duo the scene has its new size classes as the size transition starts, and the pair gets them only after
|
|
365
|
+
// UIKit laid it out in the new size: the primary first filled the whole open window, then gave half of it to the
|
|
366
|
+
// secondary. For the transition the pair takes the scene's size classes, so it lies as it will from its first layout.
|
|
367
|
+
// Only where the pair has the window's size classes: a sheet or a split view's column has its own.
|
|
368
|
+
- (void)viewWillTransitionToSize:(CGSize)size
|
|
369
|
+
withTransitionCoordinator:(id<UIViewControllerTransitionCoordinator>)coordinator {
|
|
370
|
+
[super viewWillTransitionToSize:size withTransitionCoordinator:coordinator];
|
|
371
|
+
// A new shape may leave the axes no room, or give it back: the pair takes it before its first layout in the size.
|
|
372
|
+
if (_secondaryFirst) {
|
|
373
|
+
_transitionSize = size;
|
|
374
|
+
[self arrangeForTraits:self.traitCollection];
|
|
375
|
+
__weak ANNArrangementViewController *weakPair = self;
|
|
376
|
+
void (^sized)(id<UIViewControllerTransitionCoordinatorContext>) =
|
|
377
|
+
^(id<UIViewControllerTransitionCoordinatorContext> context) {
|
|
378
|
+
ANNArrangementViewController *pair = weakPair;
|
|
379
|
+
if (pair && CGSizeEqualToSize(pair->_transitionSize, size)) {
|
|
380
|
+
pair->_transitionSize = CGSizeZero;
|
|
381
|
+
}
|
|
382
|
+
};
|
|
383
|
+
[coordinator animateAlongsideTransition:nil completion:sized];
|
|
384
|
+
}
|
|
385
|
+
UITraitCollection *scene = self.viewIfLoaded.window.windowScene.traitCollection;
|
|
386
|
+
NSNumber *large = ANNIsLargeWindow(self.traitCollection);
|
|
387
|
+
NSNumber *largeScene = scene ? ANNIsLargeWindow(scene) : nil;
|
|
388
|
+
if (!large || !largeScene || ![self hasWindowSizeClasses]) {
|
|
389
|
+
return;
|
|
390
|
+
}
|
|
391
|
+
// The size classes the pair has now are the scene's of an earlier transition, still running: this one keeps them
|
|
392
|
+
// until its own end.
|
|
393
|
+
if ([large isEqual:largeScene] && !_sceneSizeClasses) {
|
|
394
|
+
return;
|
|
395
|
+
}
|
|
396
|
+
_sceneSizeClasses = YES;
|
|
397
|
+
NSUInteger transition = ++_sceneSizeClassesTransition;
|
|
398
|
+
self.traitOverrides.horizontalSizeClass = scene.horizontalSizeClass;
|
|
399
|
+
self.traitOverrides.verticalSizeClass = scene.verticalSizeClass;
|
|
400
|
+
[self updateTraitsIfNeeded];
|
|
401
|
+
__weak ANNArrangementViewController *weakSelf = self;
|
|
402
|
+
void (^ended)(id<UIViewControllerTransitionCoordinatorContext>) =
|
|
403
|
+
^(id<UIViewControllerTransitionCoordinatorContext> context) {
|
|
404
|
+
[weakSelf dropSceneSizeClassesOfTransition:transition];
|
|
405
|
+
};
|
|
406
|
+
[coordinator animateAlongsideTransition:nil completion:ended];
|
|
407
|
+
}
|
|
408
|
+
|
|
409
|
+
- (void)dropSceneSizeClassesOfTransition:(NSUInteger)transition {
|
|
410
|
+
if (!_sceneSizeClasses || transition != _sceneSizeClassesTransition) {
|
|
411
|
+
return;
|
|
412
|
+
}
|
|
413
|
+
_sceneSizeClasses = NO;
|
|
414
|
+
[self.traitOverrides removeTrait:UITraitHorizontalSizeClass.class];
|
|
415
|
+
[self.traitOverrides removeTrait:UITraitVerticalSizeClass.class];
|
|
416
|
+
}
|
|
417
|
+
|
|
418
|
+
// The pair's size classes are the window's: it stands in the window's root, not in a presented layer, and no split
|
|
419
|
+
// view's column is between them.
|
|
420
|
+
- (BOOL)hasWindowSizeClasses {
|
|
421
|
+
UIWindow *window = self.viewIfLoaded.window;
|
|
422
|
+
if (!window) {
|
|
423
|
+
return NO;
|
|
424
|
+
}
|
|
425
|
+
UIViewController *top = self;
|
|
426
|
+
for (UIViewController *parent = self.parentViewController; parent;
|
|
427
|
+
parent = parent.parentViewController) {
|
|
428
|
+
if ([parent isKindOfClass:UISplitViewController.class]) {
|
|
429
|
+
return NO;
|
|
430
|
+
}
|
|
431
|
+
top = parent;
|
|
432
|
+
}
|
|
433
|
+
return top == window.rootViewController;
|
|
267
434
|
}
|
|
268
435
|
|
|
269
436
|
// The first state, before the pair is laid out: as UIKit lays it out in the window's shape (measured on iPhone Duo),
|
|
@@ -296,9 +463,9 @@ static BOOL ANNIsShown(UIViewController *screen, UIArrangementViewState *state,
|
|
|
296
463
|
ofScreen:(UIViewController *)screen
|
|
297
464
|
eventEmitter:(ANNEventEmitter *)eventEmitter {
|
|
298
465
|
if (ANNKeepsState(screen)) {
|
|
299
|
-
[
|
|
300
|
-
|
|
301
|
-
|
|
466
|
+
[ANNScreenEnvironment setArrangement:state
|
|
467
|
+
forScreenId:screen.layoutInfo.componentId
|
|
468
|
+
eventEmitter:eventEmitter];
|
|
302
469
|
}
|
|
303
470
|
}
|
|
304
471
|
|
|
@@ -431,13 +598,17 @@ static BOOL ANNIsShown(UIViewController *screen, UIArrangementViewState *state,
|
|
|
431
598
|
|
|
432
599
|
- (void)viewDidLayoutSubviews {
|
|
433
600
|
[super viewDidLayoutSubviews];
|
|
601
|
+
// A size of its own without a transition (a column of a split view): the axes may allow another shape now.
|
|
602
|
+
if (_secondaryFirst) {
|
|
603
|
+
[self arrangeForTraits:self.traitCollection];
|
|
604
|
+
}
|
|
434
605
|
[self setNeedsStateUpdate];
|
|
435
606
|
}
|
|
436
607
|
|
|
437
608
|
// In the window now: its own size classes, which the window's stood in for.
|
|
438
609
|
- (void)viewWillAppear:(BOOL)animated {
|
|
439
610
|
[super viewWillAppear:animated];
|
|
440
|
-
[self arrangeForTraits:self.traitCollection
|
|
611
|
+
[self arrangeForTraits:self.traitCollection];
|
|
441
612
|
}
|
|
442
613
|
|
|
443
614
|
- (void)viewDidAppear:(BOOL)animated {
|
|
@@ -477,10 +648,12 @@ static BOOL ANNIsShown(UIViewController *screen, UIArrangementViewState *state,
|
|
|
477
648
|
if (!self.viewIfLoaded.window || _screensDestroyed) {
|
|
478
649
|
return;
|
|
479
650
|
}
|
|
651
|
+
// By the screens' placements: with `primaryEdge` at the trailing side or the bottom they are the other way round,
|
|
652
|
+
// and a secondary out of its placement has none.
|
|
480
653
|
UIArrangementViewState *primaryState =
|
|
481
|
-
[self stateForPlacement:
|
|
654
|
+
[self stateForPlacement:[self placementForViewController:_primary]];
|
|
482
655
|
UIArrangementViewState *secondaryState =
|
|
483
|
-
[self stateForPlacement:
|
|
656
|
+
[self stateForPlacement:[self placementForViewController:_secondary]];
|
|
484
657
|
CGRect primaryFrame = ANNShownFrame(_primary.viewIfLoaded, self.view);
|
|
485
658
|
CGRect secondaryFrame = ANNShownFrame(_secondary.viewIfLoaded, self.view);
|
|
486
659
|
BOOL primaryShown = ANNIsShown(_primary, primaryState, primaryFrame);
|
|
@@ -496,7 +669,8 @@ static BOOL ANNIsShown(UIViewController *screen, UIArrangementViewState *state,
|
|
|
496
669
|
CGRect overlap = CGRectIntersection(primaryFrame, secondaryFrame);
|
|
497
670
|
if (!CGRectIsNull(overlap) && overlap.size.width > 1 && overlap.size.height > 1) {
|
|
498
671
|
layout = @"overlay";
|
|
499
|
-
// UIKit puts the primary over the secondary (zIndex 1 and 0)
|
|
672
|
+
// UIKit puts the primary over the secondary (zIndex 1 and 0); an overlay keeps the screens in their own
|
|
673
|
+
// placements.
|
|
500
674
|
primaryFront = primaryState.zIndex >= secondaryState.zIndex;
|
|
501
675
|
secondaryFront = !primaryFront;
|
|
502
676
|
} else {
|
|
@@ -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
|
}
|