@apexnative/navigation 1.0.0-alpha.1 → 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 +120 -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/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 +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/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
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
#import <UIKit/UIKit.h>
|
|
2
|
+
|
|
3
|
+
NS_ASSUME_NONNULL_BEGIN
|
|
4
|
+
|
|
5
|
+
/// Posted on the main queue when the screens' geometry has settled: each screen sends its insets, padding and regions
|
|
6
|
+
/// once.
|
|
7
|
+
extern NSNotificationName const ANNScreenSettlingDidEndNotification;
|
|
8
|
+
|
|
9
|
+
/// iPhone Duo (iOS 27.1) folds and unfolds in steps: around the size transition, UIKit gives the views safe areas and a
|
|
10
|
+
/// vertical bar edge that are neither the old nor the new ones (the bar on the other side, insets on both sides,
|
|
11
|
+
/// twice its width) and tells of the bar's edge and of the safe area at other moments. While the geometry settles the
|
|
12
|
+
/// screens lay out as always but send nothing to JavaScript: the settling ends once the transition is over and the
|
|
13
|
+
/// values of the screens have stood still for a short while, and the screens send what they have then. Only on a
|
|
14
|
+
/// device with a hinge: elsewhere a rotation gives the new safe area at once, and it goes at once. Main queue.
|
|
15
|
+
@interface ANNScreenSettling : NSObject
|
|
16
|
+
|
|
17
|
+
/// A size transition starts: the settling runs at least until it ends.
|
|
18
|
+
+ (void)beginWithTransition:(id<UIViewControllerTransitionCoordinator>)coordinator;
|
|
19
|
+
|
|
20
|
+
/// The vertical bar's edge changed: the size transition, when one follows, comes a little later. The hinge's moves
|
|
21
|
+
/// begin the settling too (`ANNHingeDidMoveNotification`): UIKit may give a new safe area before either.
|
|
22
|
+
+ (void)beginForTraitChange;
|
|
23
|
+
|
|
24
|
+
/// Whether the screens hold their insets now.
|
|
25
|
+
+ (BOOL)isSettling;
|
|
26
|
+
|
|
27
|
+
/// A screen's values changed while settling: the quiet time starts again.
|
|
28
|
+
+ (void)valuesDidChange;
|
|
29
|
+
|
|
30
|
+
@end
|
|
31
|
+
|
|
32
|
+
NS_ASSUME_NONNULL_END
|
|
@@ -0,0 +1,137 @@
|
|
|
1
|
+
#import "ANNScreenSettling.h"
|
|
2
|
+
#import "ANNEventContract.h"
|
|
3
|
+
#import "ANNHinge.h"
|
|
4
|
+
#import <QuartzCore/QuartzCore.h>
|
|
5
|
+
|
|
6
|
+
NSNotificationName const ANNScreenSettlingDidEndNotification = @"ANNScreenSettlingDidEnd";
|
|
7
|
+
|
|
8
|
+
// How long the values of the screens stand still before the settling ends. On iPhone Duo UIKit's last step of a fold
|
|
9
|
+
// comes some 30 ms after the size transition's end, and the size transition some 50 ms after the bar's new edge.
|
|
10
|
+
static const CFTimeInterval ANNScreenSettlingQuietTime = 0.15;
|
|
11
|
+
// The settling holds the insets no longer than this after its last start, whatever keeps changing.
|
|
12
|
+
static const CFTimeInterval ANNScreenSettlingLongest = 1.0;
|
|
13
|
+
// The degrees the hinge turns before it counts as a move: a device held half open trembles a little.
|
|
14
|
+
static const double ANNScreenSettlingHingeStep = 2;
|
|
15
|
+
|
|
16
|
+
static BOOL ANNSettling;
|
|
17
|
+
// The size transitions that began and haven't ended: each screen counts its own call of the same transition.
|
|
18
|
+
static NSInteger ANNSettlingTransitions;
|
|
19
|
+
static CFTimeInterval ANNSettlingStart;
|
|
20
|
+
static CFTimeInterval ANNSettlingLastChange;
|
|
21
|
+
// Only the check scheduled last runs.
|
|
22
|
+
static NSUInteger ANNSettlingCheckGeneration;
|
|
23
|
+
// One more at each end: a transition that began before it no longer counts.
|
|
24
|
+
static NSUInteger ANNSettlingEpoch;
|
|
25
|
+
// The hinge's state and angle at its first value and at its last move that counted; none without a hinge.
|
|
26
|
+
static id ANNSettlingHingeState;
|
|
27
|
+
static NSNumber *ANNSettlingHingeAngle;
|
|
28
|
+
|
|
29
|
+
@implementation ANNScreenSettling
|
|
30
|
+
|
|
31
|
+
// The screens ask `isSettling` from their first layout on, before any fold.
|
|
32
|
+
+ (void)initialize {
|
|
33
|
+
if (self == ANNScreenSettling.class) {
|
|
34
|
+
[NSNotificationCenter.defaultCenter addObserver:self
|
|
35
|
+
selector:@selector(hingeDidMove:)
|
|
36
|
+
name:ANNHingeDidMoveNotification
|
|
37
|
+
object:nil];
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
// A fold starts with the hinge, and the display it shows on changes as it moves.
|
|
42
|
+
+ (void)hingeDidMove:(NSNotification *)notification {
|
|
43
|
+
NSDictionary<NSString *, id> *value = [ANNHinge lastValue];
|
|
44
|
+
const auto &keys = ANNEventContract.HingeChanged;
|
|
45
|
+
id state = value[keys.state];
|
|
46
|
+
NSNumber *angle = value[keys.angle];
|
|
47
|
+
// The first value, and the hinge's coming or going, are no move.
|
|
48
|
+
if (!state || !ANNSettlingHingeState) {
|
|
49
|
+
ANNSettlingHingeState = state;
|
|
50
|
+
ANNSettlingHingeAngle = angle;
|
|
51
|
+
return;
|
|
52
|
+
}
|
|
53
|
+
double turned = fabs(angle.doubleValue - ANNSettlingHingeAngle.doubleValue);
|
|
54
|
+
BOOL moved = ![state isEqual:ANNSettlingHingeState] || !angle || !ANNSettlingHingeAngle ||
|
|
55
|
+
turned >= ANNScreenSettlingHingeStep;
|
|
56
|
+
if (!moved) {
|
|
57
|
+
return;
|
|
58
|
+
}
|
|
59
|
+
ANNSettlingHingeState = state;
|
|
60
|
+
ANNSettlingHingeAngle = angle;
|
|
61
|
+
[self beginForTraitChange];
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
+ (void)beginWithTransition:(id<UIViewControllerTransitionCoordinator>)coordinator {
|
|
65
|
+
if (![ANNHinge isPresent]) {
|
|
66
|
+
return;
|
|
67
|
+
}
|
|
68
|
+
[self begin];
|
|
69
|
+
ANNSettlingTransitions += 1;
|
|
70
|
+
NSUInteger epoch = ANNSettlingEpoch;
|
|
71
|
+
void (^ended)(id<UIViewControllerTransitionCoordinatorContext>) =
|
|
72
|
+
^(id<UIViewControllerTransitionCoordinatorContext> context) {
|
|
73
|
+
if (epoch != ANNSettlingEpoch) {
|
|
74
|
+
return;
|
|
75
|
+
}
|
|
76
|
+
ANNSettlingTransitions = MAX(0, ANNSettlingTransitions - 1);
|
|
77
|
+
[ANNScreenSettling valuesDidChange];
|
|
78
|
+
[ANNScreenSettling checkAfter:ANNScreenSettlingQuietTime];
|
|
79
|
+
};
|
|
80
|
+
[coordinator animateAlongsideTransition:nil completion:ended];
|
|
81
|
+
// The longest still holds should the transition's end never come.
|
|
82
|
+
[self checkAfter:ANNScreenSettlingLongest];
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
// Only iPhone Duo has a vertical bar: no need to ask for the hinge.
|
|
86
|
+
+ (void)beginForTraitChange {
|
|
87
|
+
[self begin];
|
|
88
|
+
[self checkAfter:ANNScreenSettlingQuietTime];
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
+ (void)begin {
|
|
92
|
+
CFTimeInterval now = CACurrentMediaTime();
|
|
93
|
+
ANNSettling = YES;
|
|
94
|
+
ANNSettlingStart = now;
|
|
95
|
+
ANNSettlingLastChange = now;
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
+ (BOOL)isSettling {
|
|
99
|
+
return ANNSettling;
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
+ (void)valuesDidChange {
|
|
103
|
+
ANNSettlingLastChange = CACurrentMediaTime();
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
+ (void)checkAfter:(CFTimeInterval)delay {
|
|
107
|
+
NSUInteger generation = ++ANNSettlingCheckGeneration;
|
|
108
|
+
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(delay * NSEC_PER_SEC)),
|
|
109
|
+
dispatch_get_main_queue(), ^{
|
|
110
|
+
if (generation == ANNSettlingCheckGeneration) {
|
|
111
|
+
[ANNScreenSettling check];
|
|
112
|
+
}
|
|
113
|
+
});
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
// Ends once no transition runs and the values stood still for the quiet time, or at the longest; else looks again
|
|
117
|
+
// when that can be the case. A change since the check was scheduled moves the end on.
|
|
118
|
+
+ (void)check {
|
|
119
|
+
if (!ANNSettling) {
|
|
120
|
+
return;
|
|
121
|
+
}
|
|
122
|
+
CFTimeInterval now = CACurrentMediaTime();
|
|
123
|
+
CFTimeInterval longest = ANNSettlingStart + ANNScreenSettlingLongest;
|
|
124
|
+
CFTimeInterval quiet = ANNSettlingLastChange + ANNScreenSettlingQuietTime;
|
|
125
|
+
if (now >= longest || (ANNSettlingTransitions == 0 && now >= quiet)) {
|
|
126
|
+
ANNSettling = NO;
|
|
127
|
+
ANNSettlingTransitions = 0;
|
|
128
|
+
ANNSettlingEpoch += 1;
|
|
129
|
+
[NSNotificationCenter.defaultCenter postNotificationName:ANNScreenSettlingDidEndNotification
|
|
130
|
+
object:nil];
|
|
131
|
+
return;
|
|
132
|
+
}
|
|
133
|
+
CFTimeInterval next = ANNSettlingTransitions > 0 ? longest : MIN(quiet, longest);
|
|
134
|
+
[self checkAfter:next - now];
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
@end
|
|
@@ -12,6 +12,14 @@ typedef NS_ENUM(NSInteger, ANNSideMenuOpenMode) {
|
|
|
12
12
|
ANNSideMenuOpenModeAboveContent,
|
|
13
13
|
};
|
|
14
14
|
|
|
15
|
+
/** `sideMenu.menusAttachMode`: when the screens of the menus are made, with the side menu, after its first
|
|
16
|
+
* appearance, or each as it first starts to open. */
|
|
17
|
+
typedef NS_ENUM(NSInteger, ANNSideMenuAttachMode) {
|
|
18
|
+
ANNSideMenuAttachModeTogether,
|
|
19
|
+
ANNSideMenuAttachModeAfterCenter,
|
|
20
|
+
ANNSideMenuAttachModeOnOpen,
|
|
21
|
+
};
|
|
22
|
+
|
|
15
23
|
/** `sideMenu.openGestureMode`: a pan from anywhere on the center, or from its edges only. */
|
|
16
24
|
typedef NS_ENUM(NSInteger, ANNSideMenuOpenGestureMode) {
|
|
17
25
|
ANNSideMenuOpenGestureModeEntireScreen,
|
|
@@ -12,6 +12,24 @@ static const CGFloat ANNSideMenuDimAlpha = 0.5;
|
|
|
12
12
|
static const CGFloat ANNSideMenuMaxStretch = 1.1;
|
|
13
13
|
static const NSTimeInterval ANNSideMenuMinimumDuration = 0.1;
|
|
14
14
|
|
|
15
|
+
// `sideMenu.menusAttachMode` of the side menu's own options, else of the defaults; any other value, and none, is
|
|
16
|
+
// `together`.
|
|
17
|
+
static ANNSideMenuAttachMode ANNSideMenuAttachModeOf(ANNNavigationOptions *options,
|
|
18
|
+
ANNNavigationOptions *defaultOptions) {
|
|
19
|
+
Text *value = options.sideMenu.menusAttachMode;
|
|
20
|
+
if (!value.hasValue) {
|
|
21
|
+
value = defaultOptions.sideMenu.menusAttachMode;
|
|
22
|
+
}
|
|
23
|
+
NSString *mode = [value withDefault:nil];
|
|
24
|
+
if ([mode isEqualToString:@"afterCenter"]) {
|
|
25
|
+
return ANNSideMenuAttachModeAfterCenter;
|
|
26
|
+
}
|
|
27
|
+
if ([mode isEqualToString:@"onOpen"]) {
|
|
28
|
+
return ANNSideMenuAttachModeOnOpen;
|
|
29
|
+
}
|
|
30
|
+
return ANNSideMenuAttachModeTogether;
|
|
31
|
+
}
|
|
32
|
+
|
|
15
33
|
static UINavigationController *ANNStackOfResponder(UIResponder *responder) {
|
|
16
34
|
for (; responder; responder = responder.nextResponder) {
|
|
17
35
|
if ([responder isKindOfClass:UINavigationController.class]) {
|
|
@@ -65,6 +83,8 @@ typedef NS_ENUM(NSInteger, ANNSideMenuAppearance) {
|
|
|
65
83
|
@property(nonatomic) BOOL glass;
|
|
66
84
|
@property(nonatomic) ANNSideMenuAppearance appearance;
|
|
67
85
|
@property(nonatomic, copy) NSString *scrimTestID;
|
|
86
|
+
// The menu's part is in its container and renders (`menusAttachMode`).
|
|
87
|
+
@property(nonatomic) BOOL attached;
|
|
68
88
|
@end
|
|
69
89
|
|
|
70
90
|
@implementation ANNSideMenuSideState
|
|
@@ -95,6 +115,8 @@ typedef NS_ENUM(NSInteger, ANNSideMenuAppearance) {
|
|
|
95
115
|
ANNSideMenuSideState *_leftState;
|
|
96
116
|
ANNSideMenuSideState *_rightState;
|
|
97
117
|
ANNSideMenuOpenGestureMode _openGestureMode;
|
|
118
|
+
ANNSideMenuAttachMode _attachMode;
|
|
119
|
+
BOOL _firstAppeared;
|
|
98
120
|
NSString *_animationType;
|
|
99
121
|
UIView *_centerContainer;
|
|
100
122
|
UIView *_leftContainer;
|
|
@@ -132,6 +154,7 @@ typedef NS_ENUM(NSInteger, ANNSideMenuAppearance) {
|
|
|
132
154
|
_leftState = [ANNSideMenuSideState new];
|
|
133
155
|
_rightState = [ANNSideMenuSideState new];
|
|
134
156
|
_openGestureMode = ANNSideMenuOpenGestureModeBezel;
|
|
157
|
+
_attachMode = ANNSideMenuAttachModeOf(options, defaultOptions);
|
|
135
158
|
[self setSideMenuChildren:childViewControllers];
|
|
136
159
|
|
|
137
160
|
self.presenter = presenter;
|
|
@@ -181,10 +204,15 @@ typedef NS_ENUM(NSInteger, ANNSideMenuAppearance) {
|
|
|
181
204
|
|
|
182
205
|
- (void)viewDidLoad {
|
|
183
206
|
[super viewDidLoad];
|
|
184
|
-
_leftContainer = [self
|
|
185
|
-
_rightContainer = [self
|
|
186
|
-
_centerContainer = [self
|
|
207
|
+
_leftContainer = [self makeContainer];
|
|
208
|
+
_rightContainer = [self makeContainer];
|
|
209
|
+
_centerContainer = [self makeContainer];
|
|
210
|
+
[self putChild:self.center into:_centerContainer];
|
|
187
211
|
_centerContainer.hidden = NO;
|
|
212
|
+
if (_attachMode == ANNSideMenuAttachModeTogether) {
|
|
213
|
+
[self attachMenu:ANNSideMenuSideLeft];
|
|
214
|
+
[self attachMenu:ANNSideMenuSideRight];
|
|
215
|
+
}
|
|
188
216
|
[self applyGlassOf:ANNSideMenuSideLeft];
|
|
189
217
|
[self applyGlassOf:ANNSideMenuSideRight];
|
|
190
218
|
|
|
@@ -200,32 +228,65 @@ typedef NS_ENUM(NSInteger, ANNSideMenuAppearance) {
|
|
|
200
228
|
[self.view addGestureRecognizer:_pan];
|
|
201
229
|
}
|
|
202
230
|
|
|
203
|
-
//
|
|
204
|
-
- (UIView *)
|
|
231
|
+
// The view of a part, which the menu moves; a menu's container is hidden while closed.
|
|
232
|
+
- (UIView *)makeContainer {
|
|
205
233
|
UIView *container = [[UIView alloc] initWithFrame:self.view.bounds];
|
|
206
234
|
container.hidden = YES;
|
|
207
235
|
[self.view addSubview:container];
|
|
208
|
-
if (child) {
|
|
209
|
-
[self addChildViewController:child];
|
|
210
|
-
child.view.frame = container.bounds;
|
|
211
|
-
child.view.autoresizingMask =
|
|
212
|
-
UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
|
|
213
|
-
[container addSubview:child.view];
|
|
214
|
-
[child didMoveToParentViewController:self];
|
|
215
|
-
}
|
|
216
236
|
return container;
|
|
217
237
|
}
|
|
218
238
|
|
|
239
|
+
// A part in its container, over the container's glass. Loading the part's view loads its node's, which renders.
|
|
240
|
+
- (void)putChild:(UIViewController *)child into:(UIView *)container {
|
|
241
|
+
if (!child) {
|
|
242
|
+
return;
|
|
243
|
+
}
|
|
244
|
+
[self addChildViewController:child];
|
|
245
|
+
child.view.frame = container.bounds;
|
|
246
|
+
child.view.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
|
|
247
|
+
[container addSubview:child.view];
|
|
248
|
+
[child didMoveToParentViewController:self];
|
|
249
|
+
}
|
|
250
|
+
|
|
251
|
+
// The menu's part goes into its container and renders, once: with the side menu's view (`together`), after its first
|
|
252
|
+
// appearance (`afterCenter`), or as the menu first starts to open (`onOpen`, and any mode for a menu that opens
|
|
253
|
+
// earlier). A menu not attached yet keeps its node and options; only its view and content wait.
|
|
254
|
+
- (void)attachMenu:(ANNSideMenuSide)side {
|
|
255
|
+
ANNSideMenuChildViewController *menu = [self menuOf:side];
|
|
256
|
+
if (!menu || [self stateOf:side].attached || self.nodeHelper.destroyed) {
|
|
257
|
+
return;
|
|
258
|
+
}
|
|
259
|
+
[self loadViewIfNeeded];
|
|
260
|
+
ANNSideMenuSideState *state = [self stateOf:side];
|
|
261
|
+
if (state.attached) {
|
|
262
|
+
return;
|
|
263
|
+
}
|
|
264
|
+
state.attached = YES;
|
|
265
|
+
[self putChild:menu into:[self containerOf:side]];
|
|
266
|
+
[menu render];
|
|
267
|
+
}
|
|
268
|
+
|
|
269
|
+
// The current part renders, and every other part that is attached or will be with the side menu's view.
|
|
219
270
|
- (void)render {
|
|
220
271
|
[self.nodeHelper render];
|
|
221
272
|
UIViewController *currentChild = self.getCurrentChild;
|
|
222
273
|
for (UIViewController *vc in _sideMenuChildren) {
|
|
223
|
-
if (vc != currentChild) {
|
|
274
|
+
if (vc != currentChild && [self rendersPart:vc]) {
|
|
224
275
|
[vc render];
|
|
225
276
|
}
|
|
226
277
|
}
|
|
227
278
|
}
|
|
228
279
|
|
|
280
|
+
- (BOOL)rendersPart:(UIViewController *)part {
|
|
281
|
+
if (part == self.left) {
|
|
282
|
+
return _attachMode == ANNSideMenuAttachModeTogether || _leftState.attached;
|
|
283
|
+
}
|
|
284
|
+
if (part == self.right) {
|
|
285
|
+
return _attachMode == ANNSideMenuAttachModeTogether || _rightState.attached;
|
|
286
|
+
}
|
|
287
|
+
return YES;
|
|
288
|
+
}
|
|
289
|
+
|
|
229
290
|
#pragma mark - Options
|
|
230
291
|
|
|
231
292
|
- (ANNSideMenuSideState *)stateOf:(ANNSideMenuSide)side {
|
|
@@ -380,6 +441,7 @@ typedef NS_ENUM(NSInteger, ANNSideMenuAppearance) {
|
|
|
380
441
|
|
|
381
442
|
// The menu on screen in its place under or over the center, its screens about to appear.
|
|
382
443
|
- (void)show:(ANNSideMenuSide)side {
|
|
444
|
+
[self attachMenu:side];
|
|
383
445
|
_side = side;
|
|
384
446
|
[self orderSide:side];
|
|
385
447
|
[self containerOf:side].hidden = NO;
|
|
@@ -586,6 +648,13 @@ typedef NS_ENUM(NSInteger, ANNSideMenuAppearance) {
|
|
|
586
648
|
if (_side != ANNSideMenuSideNone) {
|
|
587
649
|
[self side:_side transitionEnded:YES];
|
|
588
650
|
}
|
|
651
|
+
if (!_firstAppeared) {
|
|
652
|
+
_firstAppeared = YES;
|
|
653
|
+
if (_attachMode == ANNSideMenuAttachModeAfterCenter) {
|
|
654
|
+
[self attachMenu:ANNSideMenuSideLeft];
|
|
655
|
+
[self attachMenu:ANNSideMenuSideRight];
|
|
656
|
+
}
|
|
657
|
+
}
|
|
589
658
|
}
|
|
590
659
|
|
|
591
660
|
- (void)viewWillDisappear:(BOOL)animated {
|
|
@@ -15,8 +15,9 @@ NS_ASSUME_NONNULL_BEGIN
|
|
|
15
15
|
/// `showInColumn`: the push's checks of the layout (the options of the tree, what the core makes), then the screen is
|
|
16
16
|
/// made and waits by the push's rules. Once it is ready, by the state then: the source in a split view not collapsed
|
|
17
17
|
/// into its compact layout — the split view shows the screen in `column`, unless a later request of that column began
|
|
18
|
-
/// meanwhile (the last one wins
|
|
19
|
-
///
|
|
18
|
+
/// meanwhile (the last one wins; the superseded one answers when the last one does, with its own screen's id whatever
|
|
19
|
+
/// the last one's outcome, as on Android); else the source in a stack — a push over it; else a rejection. The answer
|
|
20
|
+
/// is the shown screen's id; every rejection destroys the screen.
|
|
20
21
|
+ (void)showInColumn:(NSString *)column
|
|
21
22
|
layout:(ANNLayoutNode *)layout
|
|
22
23
|
componentId:(NSString *)componentId
|
|
@@ -15,14 +15,19 @@
|
|
|
15
15
|
#import "ANNRenderWait.h"
|
|
16
16
|
#import "ANNShownScreens.h"
|
|
17
17
|
#import "ANNStackCommands.h"
|
|
18
|
+
#import "ANNStackController.h"
|
|
18
19
|
#import "ANNStackQueue.h"
|
|
19
20
|
#import "ApexNavigation+Internal.h"
|
|
20
21
|
#import "UIViewController+LayoutProtocol.h"
|
|
21
22
|
#import <React/RCTLog.h>
|
|
22
23
|
|
|
23
|
-
// The limits of the bar components of a push: title and background 1 s, buttons 0.5 s.
|
|
24
|
+
// The limits of the bar components of a push: title and background 1 s, buttons 0.5 s. With `waitForRender` unset they
|
|
25
|
+
// count from the wait's start, as a stack's push; with `true`, from the content's end.
|
|
24
26
|
static const ANNBarWaitLimits ANNColumnBarLimits = {1, 0.5};
|
|
25
27
|
|
|
28
|
+
// How long the push's wait waits for the screen's first content when `waitForRender` is not set, as a stack's push.
|
|
29
|
+
static const NSTimeInterval ANNColumnRenderLimit = 0.5;
|
|
30
|
+
|
|
26
31
|
// The split view of `node`: the node itself or the nearest of its layout parents that has columns.
|
|
27
32
|
static UIViewController *ANNSplitViewOf(UIViewController *node) {
|
|
28
33
|
for (UIViewController *parent = node; parent; parent = parent.layoutParent) {
|
|
@@ -45,17 +50,26 @@ static BOOL ANNIsOnScreen(UIViewController *node) {
|
|
|
45
50
|
|
|
46
51
|
@class ANNColumnRequest;
|
|
47
52
|
|
|
53
|
+
// A request the newest of its column superseded: its answer and the id it resolves with, its own screen's (each
|
|
54
|
+
// `showInColumn` answers its own screen, as on Android).
|
|
55
|
+
@interface ANNSupersededRequest : NSObject
|
|
56
|
+
@property(nonatomic, strong) ANNCommandAnswer *answer;
|
|
57
|
+
@property(nonatomic, copy) NSString *value;
|
|
58
|
+
@end
|
|
59
|
+
|
|
60
|
+
@implementation ANNSupersededRequest
|
|
61
|
+
@end
|
|
62
|
+
|
|
48
63
|
// "The last request of a column" (`showInColumn` step 2): one per split view and column. The newest request decides
|
|
49
|
-
//
|
|
64
|
+
// when the requests it superseded answer; each of them resolves with its own screen's id whatever the newest one's
|
|
65
|
+
// outcome, as on Android.
|
|
50
66
|
@interface ANNColumnRecord : NSObject
|
|
51
67
|
@property(nonatomic, weak, nullable) UIViewController *splitView;
|
|
52
68
|
@property(nonatomic, copy) NSString *column;
|
|
53
69
|
// Weakly: what runs the newest request holds it (the waiting requests, the split view's call, the push).
|
|
54
70
|
@property(nonatomic, weak, nullable) ANNColumnRequest *newest;
|
|
55
|
-
@property(nonatomic, strong) NSMutableArray<
|
|
71
|
+
@property(nonatomic, strong) NSMutableArray<ANNSupersededRequest *> *superseded;
|
|
56
72
|
@property(nonatomic) BOOL ended;
|
|
57
|
-
@property(nonatomic, copy, nullable) NSString *value;
|
|
58
|
-
@property(nonatomic, copy, nullable) NSString *rejection;
|
|
59
73
|
@end
|
|
60
74
|
|
|
61
75
|
@implementation ANNColumnRecord
|
|
@@ -184,10 +198,11 @@ static NSMapTable<UIViewController *, ANNColumnRecordsOfSplitView *> *ANNColumnR
|
|
|
184
198
|
return record;
|
|
185
199
|
}
|
|
186
200
|
|
|
187
|
-
// Step 1, the push's wait: `waitForRender` unset waits for the
|
|
188
|
-
// it takes (with the rule for content nobody knows of), then the bar components; `false` for nothing; nothing either
|
|
189
|
-
// while the source's place isn't seen.
|
|
190
|
-
//
|
|
201
|
+
// Step 1, the push's wait, as a stack's push: `waitForRender` unset waits for the content at most 0.5 s, `true` as long
|
|
202
|
+
// as it takes (with the rule for content nobody knows of), then the bar components; `false` for nothing; nothing either
|
|
203
|
+
// while the source's place isn't seen. The content's end waits for the calls JavaScript made by then, so that the
|
|
204
|
+
// options of the screen's first commit are applied before it shows. Read from the screen's own options over the
|
|
205
|
+
// defaults: it has no place yet. The screen waits unseen in the source's window, as a layer that waits to show.
|
|
191
206
|
+ (void)startWaitOf:(ANNColumnRequest *)request {
|
|
192
207
|
UIViewController *screen = request.screen;
|
|
193
208
|
Bool *waitForRender = [screen resolveOptionsWithDefault].animations.push.waitForRender;
|
|
@@ -198,20 +213,22 @@ static NSMapTable<UIViewController *, ANNColumnRecordsOfSplitView *> *ANNColumnR
|
|
|
198
213
|
[self readyOnNextTurnOf:request];
|
|
199
214
|
return;
|
|
200
215
|
}
|
|
201
|
-
BOOL
|
|
216
|
+
BOOL bounded = !waitForRender.hasValue;
|
|
202
217
|
__weak UIViewController *weakScreen = screen;
|
|
203
218
|
NSArray<UIViewController *> * (^screens)(void) = ^NSArray<UIViewController *> * {
|
|
204
219
|
UIViewController *waited = weakScreen;
|
|
205
220
|
return waited ? waited.waitedComponentViewControllers : @[];
|
|
206
221
|
};
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
wait.unknownContentRule =
|
|
222
|
+
ANNRenderWait *wait =
|
|
223
|
+
[[ANNRenderWait alloc] initWithContent:ANNRenderWaitContentNode
|
|
224
|
+
node:screen
|
|
225
|
+
screens:screens
|
|
226
|
+
limit:bounded ? ANNColumnRenderLimit : 0
|
|
227
|
+
bar:ANNRenderWaitBarAfterContent
|
|
228
|
+
barLimits:ANNColumnBarLimits];
|
|
229
|
+
wait.unknownContentRule = !bounded;
|
|
230
|
+
wait.settlesThroughJavaScript = YES;
|
|
231
|
+
wait.barLimitsFromStart = bounded;
|
|
215
232
|
__weak ANNColumnRequest *weakRequest = request;
|
|
216
233
|
wait.canEnd = ^BOOL {
|
|
217
234
|
ANNColumnRequest *waiting = weakRequest;
|
|
@@ -225,7 +242,7 @@ static NSMapTable<UIViewController *, ANNColumnRecordsOfSplitView *> *ANNColumnR
|
|
|
225
242
|
if (!ready) {
|
|
226
243
|
return;
|
|
227
244
|
}
|
|
228
|
-
//
|
|
245
|
+
// A screen that didn't render while parked makes its content right before it shows (as a push does).
|
|
229
246
|
[ANNSplitViewCommands render:ready];
|
|
230
247
|
if (ready.starting) {
|
|
231
248
|
[ANNSplitViewCommands readyOnNextTurnOf:ready];
|
|
@@ -233,14 +250,12 @@ static NSMapTable<UIViewController *, ANNColumnRecordsOfSplitView *> *ANNColumnR
|
|
|
233
250
|
[ANNSplitViewCommands readyOf:ready];
|
|
234
251
|
}
|
|
235
252
|
};
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
};
|
|
243
|
-
}
|
|
253
|
+
wait.setUp = ^{
|
|
254
|
+
ANNColumnRequest *waiting = weakRequest;
|
|
255
|
+
if (waiting) {
|
|
256
|
+
[ANNSplitViewCommands park:waiting];
|
|
257
|
+
}
|
|
258
|
+
};
|
|
244
259
|
request.wait = wait;
|
|
245
260
|
request.starting = YES;
|
|
246
261
|
@try {
|
|
@@ -281,6 +296,13 @@ static NSMapTable<UIViewController *, ANNColumnRecordsOfSplitView *> *ANNColumnR
|
|
|
281
296
|
[screen setWaitForRender:YES];
|
|
282
297
|
}
|
|
283
298
|
if (window) {
|
|
299
|
+
__weak ANNColumnRequest *placed = request;
|
|
300
|
+
ANNScreenPlace * (^place)(void) = ^ANNScreenPlace * {
|
|
301
|
+
return [ANNSplitViewCommands placeOf:placed];
|
|
302
|
+
};
|
|
303
|
+
for (ANNComponentViewController *each in ANNStackScreensOfEntry(screen)) {
|
|
304
|
+
each.placeWhileParked = place;
|
|
305
|
+
}
|
|
284
306
|
request.parking = [ANNParking new];
|
|
285
307
|
[request.parking park:screen inView:window];
|
|
286
308
|
}
|
|
@@ -304,6 +326,34 @@ static NSMapTable<UIViewController *, ANNColumnRecordsOfSplitView *> *ANNColumnR
|
|
|
304
326
|
}
|
|
305
327
|
}
|
|
306
328
|
|
|
329
|
+
// Where the parked screen will show, as far as it is known now: the column's stack (whose screens it replaces), the
|
|
330
|
+
// navigation controller UIKit keeps a column that is a screen alone in, or the source's stack while the split view
|
|
331
|
+
// shows as one stack. Nil without one: the screen lays out with its view's own safe area.
|
|
332
|
+
+ (nullable ANNScreenPlace *)placeOf:(ANNColumnRequest *)request {
|
|
333
|
+
UIViewController *screen = request.screen;
|
|
334
|
+
UIViewController *source = request.source;
|
|
335
|
+
if (!screen || !source) {
|
|
336
|
+
return nil;
|
|
337
|
+
}
|
|
338
|
+
UIViewController *splitView = ANNSplitViewOf(source);
|
|
339
|
+
UINavigationController *stack = nil;
|
|
340
|
+
if (splitView && !ANNIsCollapsedIntoCompact(splitView)) {
|
|
341
|
+
UIViewController *columnNode =
|
|
342
|
+
[(id<ANNLayoutProtocol>)splitView viewControllerOfColumn:request.column];
|
|
343
|
+
stack = [columnNode isKindOfClass:UINavigationController.class]
|
|
344
|
+
? (UINavigationController *)columnNode
|
|
345
|
+
: columnNode.navigationController;
|
|
346
|
+
} else {
|
|
347
|
+
stack = [ANNStackCommands stackOf:source].shownNavigationController;
|
|
348
|
+
}
|
|
349
|
+
if (!stack) {
|
|
350
|
+
return nil;
|
|
351
|
+
}
|
|
352
|
+
return [ANNScreenPlace placeOfEntry:screen
|
|
353
|
+
inStack:stack
|
|
354
|
+
options:[ANNStackOptionsScreen(screen) resolveOptionsWithDefault]];
|
|
355
|
+
}
|
|
356
|
+
|
|
307
357
|
// The screen leaves its place and the waiting requests; UIKit ends its departure from the window here (it shows in
|
|
308
358
|
// this turn, or goes).
|
|
309
359
|
+ (void)leaveWaitingPlace:(ANNColumnRequest *)request {
|
|
@@ -353,18 +403,23 @@ static NSMapTable<UIViewController *, ANNColumnRecordsOfSplitView *> *ANNColumnR
|
|
|
353
403
|
[self request:request endedWithValue:nil rejection:text];
|
|
354
404
|
}
|
|
355
405
|
|
|
356
|
-
// Superseded at its readiness: its screen goes without having shown (no events)
|
|
357
|
-
//
|
|
406
|
+
// Superseded at its readiness: its screen goes without having shown (no events). It answers when the newest request
|
|
407
|
+
// does, at once when that answered, with its own screen's id: the newest one's rejection (a container for a stack
|
|
408
|
+
// column, a split view that went) is about that request only.
|
|
358
409
|
+ (void)supersede:(ANNColumnRequest *)request {
|
|
359
410
|
[self leaveWaitingPlace:request];
|
|
360
411
|
request.done = YES;
|
|
412
|
+
NSString *value = ANNStackAnswerIdOf(request.screen, ANNStackAnswerCommandShowInColumn);
|
|
361
413
|
[request.screen destroy];
|
|
362
414
|
ANNColumnRecord *record = request.record;
|
|
363
415
|
if (record.ended) {
|
|
364
|
-
[
|
|
416
|
+
[request.answer resolve:value];
|
|
365
417
|
return;
|
|
366
418
|
}
|
|
367
|
-
|
|
419
|
+
ANNSupersededRequest *superseded = [ANNSupersededRequest new];
|
|
420
|
+
superseded.answer = request.answer;
|
|
421
|
+
superseded.value = value;
|
|
422
|
+
[record.superseded addObject:superseded];
|
|
368
423
|
}
|
|
369
424
|
|
|
370
425
|
// (a) The split view shows the screen in the column: a stack column's screens are replaced without an animation and
|
|
@@ -373,14 +428,26 @@ static NSMapTable<UIViewController *, ANNColumnRecordsOfSplitView *> *ANNColumnR
|
|
|
373
428
|
// `DidDisappear` of the screens that left, `DidAppear` of the new one, the state, then the answer.
|
|
374
429
|
+ (void)show:(ANNColumnRequest *)request inSplitView:(UIViewController *)splitView {
|
|
375
430
|
UIViewController *screen = request.screen;
|
|
431
|
+
UIViewController *columnNode =
|
|
432
|
+
[(id<ANNLayoutProtocol>)splitView viewControllerOfColumn:request.column];
|
|
433
|
+
// A stack column takes what a stack takes, a screen or a pair; any other layout rejects `columnIsStack`, as on
|
|
434
|
+
// Android. A column that is a screen alone takes any layout in its place.
|
|
435
|
+
if ([columnNode isKindOfClass:UINavigationController.class] &&
|
|
436
|
+
[ANNLayoutValidator checkStackChild:request.layout
|
|
437
|
+
stackId:columnNode.layoutInfo.componentId ?: @""]) {
|
|
438
|
+
[self leaveWaitingPlace:request];
|
|
439
|
+
[screen destroy];
|
|
440
|
+
[self request:request
|
|
441
|
+
endedWithValue:nil
|
|
442
|
+
rejection:[ANNErrorTexts columnIsStack:request.componentId column:request.column]];
|
|
443
|
+
return;
|
|
444
|
+
}
|
|
376
445
|
// Before the parking lets go of it, so that UIKit's calls stay silent until the end.
|
|
377
446
|
[ANNAppearanceDispatcher driveAppearanceOf:@[ screen ]];
|
|
378
447
|
request.driven = YES;
|
|
379
448
|
[self leaveWaitingPlace:request];
|
|
380
449
|
// A screen alone in a column has the split view as its parent by the layout (UIKit puts it into a navigation
|
|
381
450
|
// controller of its own); a stack column's stack is its parent.
|
|
382
|
-
UIViewController *columnNode =
|
|
383
|
-
[(id<ANNLayoutProtocol>)splitView viewControllerOfColumn:request.column];
|
|
384
451
|
if (columnNode && ![columnNode isKindOfClass:UINavigationController.class]) {
|
|
385
452
|
[screen setExplicitLayoutParent:splitView];
|
|
386
453
|
}
|
|
@@ -485,7 +552,8 @@ static NSMapTable<UIViewController *, ANNColumnRecordsOfSplitView *> *ANNColumnR
|
|
|
485
552
|
|
|
486
553
|
#pragma mark - The answers
|
|
487
554
|
|
|
488
|
-
// The request answers once; when it is the newest of its column, the requests it superseded answer
|
|
555
|
+
// The request answers once; when it is the newest of its column, the requests it superseded answer then, each with its
|
|
556
|
+
// own screen's id.
|
|
489
557
|
+ (void)request:(ANNColumnRequest *)request
|
|
490
558
|
endedWithValue:(NSString *)value
|
|
491
559
|
rejection:(NSString *)rejection {
|
|
@@ -499,13 +567,11 @@ static NSMapTable<UIViewController *, ANNColumnRecordsOfSplitView *> *ANNColumnR
|
|
|
499
567
|
return;
|
|
500
568
|
}
|
|
501
569
|
record.ended = YES;
|
|
502
|
-
record.value = value;
|
|
503
|
-
record.rejection = rejection;
|
|
504
570
|
record.newest = nil;
|
|
505
|
-
NSArray<
|
|
571
|
+
NSArray<ANNSupersededRequest *> *superseded = [record.superseded copy];
|
|
506
572
|
[record.superseded removeAllObjects];
|
|
507
|
-
for (
|
|
508
|
-
[
|
|
573
|
+
for (ANNSupersededRequest *each in superseded) {
|
|
574
|
+
[each.answer resolve:each.value];
|
|
509
575
|
}
|
|
510
576
|
// A request that begins from now on starts a record of its own.
|
|
511
577
|
UIViewController *splitView = record.splitView;
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
#import "ANNSplitViewController.h"
|
|
2
2
|
#import "ANNErrorHandler.h"
|
|
3
|
+
#import "ANNErrorTexts.h"
|
|
3
4
|
#import "ANNShownScreens.h"
|
|
4
5
|
#import "UISplitViewController+ANNOptions.h"
|
|
5
6
|
#import "UIViewController+LayoutProtocol.h"
|
|
@@ -213,23 +214,21 @@ static UISplitViewControllerColumn ANNSplitViewColumn(NSString *name) {
|
|
|
213
214
|
completion:(ANNTransitionCompletionBlock)completion
|
|
214
215
|
rejection:(ANNTransitionRejectionBlock)rejection {
|
|
215
216
|
UIViewController *previous = _columns[column];
|
|
217
|
+
NSString *fromId = fromViewController.layoutInfo.componentId ?: @"";
|
|
216
218
|
if (!previous) {
|
|
217
|
-
rejection([
|
|
218
|
-
fromViewController.layoutInfo.componentId, column],
|
|
219
|
-
nil);
|
|
219
|
+
rejection([ANNErrorTexts noSuchColumn:fromId column:column], nil);
|
|
220
220
|
return;
|
|
221
221
|
}
|
|
222
222
|
if ([previous isKindOfClass:UINavigationController.class]) {
|
|
223
|
-
// UIKit does not take a navigation controller among the screens of another.
|
|
223
|
+
// UIKit does not take a navigation controller among the screens of another. The core rejects every layout a
|
|
224
|
+
// stack doesn't take before it asks; this guards the module's own call.
|
|
224
225
|
if ([screen isKindOfClass:UINavigationController.class]) {
|
|
225
|
-
rejection([
|
|
226
|
-
@"stack: it takes a screen, not a stack",
|
|
227
|
-
column, fromViewController.layoutInfo.componentId],
|
|
228
|
-
nil);
|
|
226
|
+
rejection([ANNErrorTexts columnIsStack:fromId column:column], nil);
|
|
229
227
|
return;
|
|
230
228
|
}
|
|
231
229
|
// In place, as a column of UIKit apps changes; UIKit animates a column it brings on top.
|
|
232
230
|
[(UINavigationController *)previous setStackChildren:@[ screen ]
|
|
231
|
+
inColumn:column
|
|
233
232
|
fromViewController:fromViewController
|
|
234
233
|
animated:NO
|
|
235
234
|
completion:^{
|