@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
|
@@ -1,39 +1,85 @@
|
|
|
1
1
|
#import "ANNFrameDriver.h"
|
|
2
2
|
#import "ANNAssert.h"
|
|
3
3
|
#import "ANNCurve.h"
|
|
4
|
-
#import
|
|
4
|
+
#import "ANNTransformParts.h"
|
|
5
|
+
#include <cmath>
|
|
5
6
|
|
|
6
|
-
// The
|
|
7
|
-
|
|
8
|
-
@interface ANNFrameTarget : NSObject
|
|
9
|
-
@property(nonatomic, weak) id owner;
|
|
10
|
-
@end
|
|
7
|
+
// The samples per second of a client's values: a frame of a 120 Hz display each.
|
|
8
|
+
static const double ANNSamplesPerSecond = 120;
|
|
11
9
|
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
@end
|
|
10
|
+
// At most this many samples per client: a longer transition samples less often.
|
|
11
|
+
static const NSUInteger ANNMaxSamples = 2400;
|
|
15
12
|
|
|
16
|
-
|
|
13
|
+
NSArray<NSNumber *> *ANNSampleTimes(NSTimeInterval end, NSTimeInterval length,
|
|
14
|
+
NSArray<NSNumber *> *marks) {
|
|
15
|
+
end = MIN(MAX(end, 0), length);
|
|
16
|
+
NSMutableArray<NSNumber *> *candidates = [NSMutableArray arrayWithObject:@0];
|
|
17
|
+
double step = MAX(1 / ANNSamplesPerSecond, end / ANNMaxSamples);
|
|
18
|
+
NSUInteger count = (NSUInteger)std::floor(end / step);
|
|
19
|
+
for (NSUInteger index = 1; index <= count; index++) {
|
|
20
|
+
[candidates addObject:@(index * step)];
|
|
21
|
+
}
|
|
22
|
+
for (NSNumber *mark in marks) {
|
|
23
|
+
double time = mark.doubleValue;
|
|
24
|
+
if (std::isfinite(time) && time > 0 && time < end) {
|
|
25
|
+
[candidates addObject:mark];
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
[candidates addObject:@(end)];
|
|
29
|
+
[candidates addObject:@(length)];
|
|
30
|
+
[candidates sortUsingSelector:@selector(compare:)];
|
|
31
|
+
NSMutableArray<NSNumber *> *times = [NSMutableArray arrayWithCapacity:candidates.count];
|
|
32
|
+
for (NSNumber *time in candidates) {
|
|
33
|
+
// Samples closer than a microsecond are one.
|
|
34
|
+
if (times.count == 0 || time.doubleValue - times.lastObject.doubleValue > 1e-6) {
|
|
35
|
+
[times addObject:time];
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
return times;
|
|
39
|
+
}
|
|
17
40
|
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
if (
|
|
21
|
-
|
|
22
|
-
|
|
41
|
+
CAKeyframeAnimation *ANNKeyframes(NSString *keyPath, NSArray *values, NSArray<NSNumber *> *times,
|
|
42
|
+
NSTimeInterval length) {
|
|
43
|
+
if (length <= 0 || values.count == 0 || values.count != times.count) {
|
|
44
|
+
return nil;
|
|
45
|
+
}
|
|
46
|
+
NSMutableArray<NSNumber *> *keyTimes = [NSMutableArray arrayWithCapacity:times.count];
|
|
47
|
+
for (NSNumber *time in times) {
|
|
48
|
+
[keyTimes addObject:@(MIN(MAX(time.doubleValue / length, 0.0), 1.0))];
|
|
23
49
|
}
|
|
24
|
-
[
|
|
50
|
+
CAKeyframeAnimation *animation = [CAKeyframeAnimation animationWithKeyPath:keyPath];
|
|
51
|
+
animation.values = values;
|
|
52
|
+
animation.keyTimes = keyTimes;
|
|
53
|
+
animation.calculationMode = kCAAnimationLinear;
|
|
54
|
+
animation.duration = length;
|
|
55
|
+
animation.fillMode = kCAFillModeBoth;
|
|
56
|
+
animation.removedOnCompletion = NO;
|
|
57
|
+
return animation;
|
|
25
58
|
}
|
|
26
59
|
|
|
27
|
-
|
|
60
|
+
NSString *ANNAnimationKey(NSString *keyPath) {
|
|
61
|
+
return [@"ApexNavigation." stringByAppendingString:keyPath];
|
|
62
|
+
}
|
|
28
63
|
|
|
29
64
|
@implementation ANNFrameDriver {
|
|
30
65
|
NSArray<id<ANNFrameClient>> *_clients;
|
|
31
66
|
NSTimeInterval _length;
|
|
32
|
-
CADisplayLink *_link;
|
|
33
|
-
CFTimeInterval _start;
|
|
34
67
|
dispatch_block_t _done;
|
|
35
|
-
|
|
36
|
-
|
|
68
|
+
BOOL _running;
|
|
69
|
+
BOOL _starting;
|
|
70
|
+
// When the animations were added; they start at the commit of the current transaction, a moment later.
|
|
71
|
+
CFTimeInterval _start;
|
|
72
|
+
// The driver keeps itself while its animations run: the transition that started it needn't.
|
|
73
|
+
ANNFrameDriver *_keep;
|
|
74
|
+
// A transition that follows a gesture: the layer whose time stops, its timing before, the clock's time the
|
|
75
|
+
// animations started at, the `done` that tells how it ended, and whether its end plays.
|
|
76
|
+
CALayer *_clock;
|
|
77
|
+
float _clockSpeed;
|
|
78
|
+
CFTimeInterval _clockBegin;
|
|
79
|
+
CFTimeInterval _clockOffset;
|
|
80
|
+
CFTimeInterval _base;
|
|
81
|
+
void (^_pausedDone)(BOOL finished);
|
|
82
|
+
BOOL _ending;
|
|
37
83
|
}
|
|
38
84
|
|
|
39
85
|
- (instancetype)initWithClients:(NSArray<id<ANNFrameClient>> *)clients
|
|
@@ -50,77 +96,187 @@
|
|
|
50
96
|
}
|
|
51
97
|
|
|
52
98
|
- (BOOL)isRunning {
|
|
53
|
-
return
|
|
99
|
+
return _running;
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
- (NSTimeInterval)length {
|
|
103
|
+
return _length;
|
|
54
104
|
}
|
|
55
105
|
|
|
56
106
|
- (void)startWithDone:(dispatch_block_t)done {
|
|
57
107
|
ANNAssertMainQueue();
|
|
58
108
|
#if DEBUG
|
|
59
109
|
ANNCurveSelfCheck();
|
|
110
|
+
ANNTransformPartsSelfCheck();
|
|
60
111
|
#endif
|
|
61
|
-
if (
|
|
112
|
+
if (_running || _done || _pausedDone) {
|
|
62
113
|
return;
|
|
63
114
|
}
|
|
64
115
|
_done = [done copy];
|
|
65
|
-
_running =
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
target.owner = self;
|
|
69
|
-
_link = [CADisplayLink displayLinkWithTarget:target selector:@selector(frame:)];
|
|
70
|
-
[_link addToRunLoop:NSRunLoop.mainRunLoop forMode:NSRunLoopCommonModes];
|
|
116
|
+
_running = YES;
|
|
117
|
+
_keep = self;
|
|
118
|
+
_starting = YES;
|
|
71
119
|
_start = CACurrentMediaTime();
|
|
120
|
+
__weak ANNFrameDriver *weakSelf = self;
|
|
121
|
+
[CATransaction begin];
|
|
122
|
+
[CATransaction setDisableActions:YES];
|
|
123
|
+
// Called once every animation added in this transaction ended or was removed (with its layer too), and at once
|
|
124
|
+
// without any.
|
|
125
|
+
[CATransaction setCompletionBlock:^{
|
|
126
|
+
[weakSelf animationsEnded];
|
|
127
|
+
}];
|
|
128
|
+
@try {
|
|
129
|
+
for (id<ANNFrameClient> client in _clients) {
|
|
130
|
+
[client addAnimationsWithLength:_length];
|
|
131
|
+
}
|
|
132
|
+
} @finally {
|
|
133
|
+
[CATransaction commit];
|
|
134
|
+
_starting = NO;
|
|
135
|
+
}
|
|
72
136
|
}
|
|
73
137
|
|
|
74
|
-
- (void)
|
|
75
|
-
if (
|
|
76
|
-
[link invalidate];
|
|
138
|
+
- (void)animationsEnded {
|
|
139
|
+
if (!_running) {
|
|
77
140
|
return;
|
|
78
141
|
}
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
if (
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
_running = nil;
|
|
89
|
-
if (done) {
|
|
90
|
-
done();
|
|
91
|
-
}
|
|
142
|
+
// `done` never comes inside `startWithDone:`, nor before the length passed: a transition with nothing to play (no
|
|
143
|
+
// client, every element skipped) or whose animations went early still takes its time, as on Android.
|
|
144
|
+
__weak ANNFrameDriver *weakSelf = self;
|
|
145
|
+
NSTimeInterval left = _length - (CACurrentMediaTime() - _start);
|
|
146
|
+
if (_starting || left > 0) {
|
|
147
|
+
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(MAX(left, 0) * NSEC_PER_SEC)),
|
|
148
|
+
dispatch_get_main_queue(), ^{
|
|
149
|
+
[weakSelf animationsEnded];
|
|
150
|
+
});
|
|
92
151
|
return;
|
|
93
152
|
}
|
|
94
|
-
|
|
153
|
+
_running = NO;
|
|
154
|
+
dispatch_block_t done = _done;
|
|
155
|
+
_done = nil;
|
|
156
|
+
_keep = nil;
|
|
157
|
+
if (done) {
|
|
158
|
+
done();
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
- (void)cancel {
|
|
163
|
+
ANNAssertMainQueue();
|
|
164
|
+
if (!_running) {
|
|
165
|
+
return;
|
|
166
|
+
}
|
|
167
|
+
_running = NO;
|
|
168
|
+
_done = nil;
|
|
169
|
+
_pausedDone = nil;
|
|
170
|
+
_keep = nil;
|
|
171
|
+
[self releaseClock];
|
|
95
172
|
}
|
|
96
173
|
|
|
97
|
-
-
|
|
174
|
+
#pragma mark - Following a gesture
|
|
175
|
+
|
|
176
|
+
- (void)startPausedOn:(CALayer *)clock done:(void (^)(BOOL finished))done {
|
|
177
|
+
ANNAssertMainQueue();
|
|
178
|
+
if (_running || _done || _pausedDone) {
|
|
179
|
+
return;
|
|
180
|
+
}
|
|
181
|
+
_pausedDone = [done copy];
|
|
182
|
+
_running = YES;
|
|
183
|
+
_keep = self;
|
|
184
|
+
_clock = clock;
|
|
185
|
+
_clockSpeed = clock.speed;
|
|
186
|
+
_clockBegin = clock.beginTime;
|
|
187
|
+
_clockOffset = clock.timeOffset;
|
|
188
|
+
// The clock stops at its time now: what else animates under it holds still, and the animations added now start
|
|
189
|
+
// there (Core Animation gives an animation without a begin time the layer's time at the commit).
|
|
190
|
+
_base = [clock convertTime:CACurrentMediaTime() fromLayer:nil];
|
|
98
191
|
[CATransaction begin];
|
|
99
192
|
[CATransaction setDisableActions:YES];
|
|
100
|
-
|
|
101
|
-
|
|
193
|
+
clock.speed = 0;
|
|
194
|
+
clock.beginTime = 0;
|
|
195
|
+
clock.timeOffset = _base;
|
|
196
|
+
@try {
|
|
197
|
+
for (id<ANNFrameClient> client in _clients) {
|
|
198
|
+
[client addAnimationsWithLength:_length];
|
|
199
|
+
}
|
|
200
|
+
} @finally {
|
|
201
|
+
[CATransaction commit];
|
|
202
|
+
}
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
- (void)setProgress:(CGFloat)progress {
|
|
206
|
+
ANNAssertMainQueue();
|
|
207
|
+
if (!_running || !_pausedDone || _ending) {
|
|
208
|
+
return;
|
|
102
209
|
}
|
|
210
|
+
[CATransaction begin];
|
|
211
|
+
[CATransaction setDisableActions:YES];
|
|
212
|
+
_clock.timeOffset = _base + MIN(MAX(progress, 0.0), 1.0) * _length;
|
|
103
213
|
[CATransaction commit];
|
|
104
214
|
}
|
|
105
215
|
|
|
106
|
-
- (void)
|
|
107
|
-
[
|
|
108
|
-
_link = nil;
|
|
216
|
+
- (void)finishWithSpeed:(CGFloat)speed {
|
|
217
|
+
[self playOnForward:YES speed:speed];
|
|
109
218
|
}
|
|
110
219
|
|
|
111
|
-
- (void)
|
|
220
|
+
- (void)rewindWithSpeed:(CGFloat)speed {
|
|
221
|
+
[self playOnForward:NO speed:speed];
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
// The clock runs again from where it shows, forward or back, and `done` comes once it reached the end or the start.
|
|
225
|
+
- (void)playOnForward:(BOOL)forward speed:(CGFloat)speed {
|
|
112
226
|
ANNAssertMainQueue();
|
|
113
|
-
if (!
|
|
227
|
+
if (!_running || !_pausedDone || _ending) {
|
|
114
228
|
return;
|
|
115
229
|
}
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
230
|
+
_ending = YES;
|
|
231
|
+
speed = MAX(speed, 1.0);
|
|
232
|
+
CALayer *clock = _clock;
|
|
233
|
+
CFTimeInterval at = clock.timeOffset - _base;
|
|
234
|
+
CFTimeInterval left = forward ? _length - at : at;
|
|
235
|
+
CALayer *parent = clock.superlayer;
|
|
236
|
+
CFTimeInterval now = parent ? [parent convertTime:CACurrentMediaTime() fromLayer:nil]
|
|
237
|
+
: CACurrentMediaTime();
|
|
238
|
+
[CATransaction begin];
|
|
239
|
+
[CATransaction setDisableActions:YES];
|
|
240
|
+
// The clock's time is (parent's time - beginTime) * speed + timeOffset: it goes on from where it shows.
|
|
241
|
+
clock.beginTime = now;
|
|
242
|
+
clock.speed = (float)(forward ? speed : -speed);
|
|
243
|
+
[CATransaction commit];
|
|
244
|
+
__weak ANNFrameDriver *weakSelf = self;
|
|
245
|
+
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(MAX(left / speed, 0) * NSEC_PER_SEC)),
|
|
246
|
+
dispatch_get_main_queue(), ^{
|
|
247
|
+
[weakSelf pausedEndedForward:forward];
|
|
248
|
+
});
|
|
120
249
|
}
|
|
121
250
|
|
|
122
|
-
- (void)
|
|
123
|
-
|
|
251
|
+
- (void)pausedEndedForward:(BOOL)forward {
|
|
252
|
+
if (!_running || !_pausedDone) {
|
|
253
|
+
return;
|
|
254
|
+
}
|
|
255
|
+
_running = NO;
|
|
256
|
+
void (^done)(BOOL) = _pausedDone;
|
|
257
|
+
_pausedDone = nil;
|
|
258
|
+
_keep = nil;
|
|
259
|
+
// The clock's time back and the caller's restore in one commit: between two, the animations would show at the
|
|
260
|
+
// clock's own time for a frame (past their end, or part way).
|
|
261
|
+
[CATransaction begin];
|
|
262
|
+
[self releaseClock];
|
|
263
|
+
done(forward);
|
|
264
|
+
[CATransaction commit];
|
|
265
|
+
}
|
|
266
|
+
|
|
267
|
+
// The clock gets back the timing it had before the gesture.
|
|
268
|
+
- (void)releaseClock {
|
|
269
|
+
CALayer *clock = _clock;
|
|
270
|
+
_clock = nil;
|
|
271
|
+
if (!clock) {
|
|
272
|
+
return;
|
|
273
|
+
}
|
|
274
|
+
[CATransaction begin];
|
|
275
|
+
[CATransaction setDisableActions:YES];
|
|
276
|
+
clock.speed = _clockSpeed;
|
|
277
|
+
clock.beginTime = _clockBegin;
|
|
278
|
+
clock.timeOffset = _clockOffset;
|
|
279
|
+
[CATransaction commit];
|
|
124
280
|
}
|
|
125
281
|
|
|
126
282
|
@end
|
|
@@ -12,10 +12,10 @@ NS_ASSUME_NONNULL_BEGIN
|
|
|
12
12
|
/// above the leaving one (push, `setStackRoot`, show) or below it (pop, dismissal), gets its final frame and lays out
|
|
13
13
|
/// (React gets its final size), and hides (alpha 0) until the start; a forward transition starts after its wait
|
|
14
14
|
/// (`ANNTransitionWait`), a backward one at once. Then one frame driver moves the sides that play, the elements in
|
|
15
|
-
/// place and the shared elements' copies; a side that doesn't play doesn't move. At the end, before
|
|
16
|
-
/// `completeTransition:`, the
|
|
17
|
-
///
|
|
18
|
-
/// comes inside `animateTransition:`. Main queue.
|
|
15
|
+
/// place and the shared elements' copies, in Core Animation; a side that doesn't play doesn't move. At the end, before
|
|
16
|
+
/// `completeTransition:`, the animations go, the copies go and the React views show again, and both views get back the
|
|
17
|
+
/// transform and the alpha they had. Only a pop of the swipe back follows a gesture (`animateFollowingGesture:`) and
|
|
18
|
+
/// can end where it began; `completeTransition:` never comes inside `animateTransition:`. Main queue.
|
|
19
19
|
@interface ANNTransitionAnimator : NSObject <UIViewControllerAnimatedTransitioning>
|
|
20
20
|
|
|
21
21
|
- (instancetype)initWithPlan:(ANNTransitionPlan *)plan NS_DESIGNATED_INITIALIZER;
|
|
@@ -25,8 +25,29 @@ NS_ASSUME_NONNULL_BEGIN
|
|
|
25
25
|
|
|
26
26
|
@property(nonatomic, strong, readonly) ANNTransitionPlan *plan;
|
|
27
27
|
|
|
28
|
+
/// The start of an interactive transition (a pop of the swipe back, which never waits): as `animateTransition:`, with
|
|
29
|
+
/// the frames held at their start until `setProgress:` moves them (`ANNFrameDriver startPausedOn:`); then
|
|
30
|
+
/// `finishWithSpeed:` or `rewindWithSpeed:`, after the context's own finish or cancel, plays the end.
|
|
31
|
+
- (void)animateFollowingGesture:(id<UIViewControllerContextTransitioning>)transitionContext;
|
|
32
|
+
|
|
33
|
+
/// The frames show at `progress` (0 to 1) of the length.
|
|
34
|
+
- (void)setProgress:(CGFloat)progress;
|
|
35
|
+
|
|
36
|
+
/// The rest plays (`speed` times as fast, 1 or more), and the transition completes.
|
|
37
|
+
- (void)finishWithSpeed:(CGFloat)speed;
|
|
38
|
+
|
|
39
|
+
/// The frames play back to the start (`speed` times as fast, 1 or more), and the transition completes cancelled.
|
|
40
|
+
- (void)rewindWithSpeed:(CGFloat)speed;
|
|
41
|
+
|
|
42
|
+
/// The seconds the frames take: the plan's length, or the end of a longer element.
|
|
43
|
+
@property(nonatomic, readonly) NSTimeInterval length;
|
|
44
|
+
|
|
45
|
+
/// The transition completed (or was never started).
|
|
46
|
+
@property(nonatomic, readonly) BOOL isCompleted;
|
|
47
|
+
|
|
28
48
|
/// A destroy or a reload during the transition: the wait or the frames stop at the end state, every value written goes
|
|
29
|
-
/// back, and the transition completes so that UIKit isn't left half way
|
|
49
|
+
/// back, and the transition completes so that UIKit isn't left half way (an interactive one finishes first). Nothing
|
|
50
|
+
/// once it completed.
|
|
30
51
|
- (void)cancel;
|
|
31
52
|
|
|
32
53
|
@end
|
|
@@ -33,6 +33,9 @@ static void ANNUpdateRootLayoutOf(UIViewController *node) {
|
|
|
33
33
|
NSArray<id<ANNFrameClient>> *_clients;
|
|
34
34
|
BOOL _began;
|
|
35
35
|
BOOL _completed;
|
|
36
|
+
// The transition follows a gesture (`animateFollowingGesture:`), and its end was chosen.
|
|
37
|
+
BOOL _followsGesture;
|
|
38
|
+
BOOL _endChosen;
|
|
36
39
|
// The container's views of the transition that got a depth for it, and the depth each had.
|
|
37
40
|
NSArray<UIView *> *_depthViews;
|
|
38
41
|
NSArray<NSNumber *> *_depthsBefore;
|
|
@@ -118,6 +121,33 @@ static void ANNUpdateRootLayoutOf(UIViewController *node) {
|
|
|
118
121
|
[self begin];
|
|
119
122
|
}
|
|
120
123
|
|
|
124
|
+
- (void)animateFollowingGesture:(id<UIViewControllerContextTransitioning>)transitionContext {
|
|
125
|
+
_followsGesture = YES;
|
|
126
|
+
[self animateTransition:transitionContext];
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
- (void)setProgress:(CGFloat)progress {
|
|
130
|
+
[_driver setProgress:progress];
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
- (void)finishWithSpeed:(CGFloat)speed {
|
|
134
|
+
_endChosen = YES;
|
|
135
|
+
[_driver finishWithSpeed:speed];
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
- (void)rewindWithSpeed:(CGFloat)speed {
|
|
139
|
+
_endChosen = YES;
|
|
140
|
+
[_driver rewindWithSpeed:speed];
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
- (NSTimeInterval)length {
|
|
144
|
+
return _driver ? _driver.length : _plan.length;
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
- (BOOL)isCompleted {
|
|
148
|
+
return _completed || !_context;
|
|
149
|
+
}
|
|
150
|
+
|
|
121
151
|
- (void)animationEnded:(BOOL)transitionCompleted {
|
|
122
152
|
_wait = nil;
|
|
123
153
|
_driver = nil;
|
|
@@ -133,19 +163,16 @@ static void ANNUpdateRootLayoutOf(UIViewController *node) {
|
|
|
133
163
|
_began = YES;
|
|
134
164
|
_wait = nil;
|
|
135
165
|
UIView *container = _context.containerView;
|
|
136
|
-
|
|
137
|
-
|
|
166
|
+
ANNTransitionViews *views = [[ANNTransitionViews alloc] initWithPairs:_plan.sharedElements
|
|
167
|
+
elements:_plan.elements
|
|
168
|
+
fromNode:_plan.fromNode
|
|
169
|
+
toNode:_plan.toNode];
|
|
138
170
|
NSMutableArray<id<ANNFrameClient>> *clients = [NSMutableArray new];
|
|
139
171
|
// The shared pairs first: their geometry and pictures are taken while the screens are still at rest.
|
|
140
172
|
NSArray<ANNSharedElementFlight *> *flights =
|
|
141
|
-
[ANNSharedElementFlight flightsOf:_plan.sharedElements
|
|
142
|
-
leavingRoot:leavingRoot
|
|
143
|
-
arrivingRoot:arrivingRoot
|
|
144
|
-
container:container];
|
|
173
|
+
[ANNSharedElementFlight flightsOf:_plan.sharedElements views:views container:container];
|
|
145
174
|
NSArray<ANNElementTransition *> *elements =
|
|
146
|
-
[ANNElementTransition transitionsOf:_plan.elements
|
|
147
|
-
leavingRoot:leavingRoot
|
|
148
|
-
arrivingRoot:arrivingRoot];
|
|
175
|
+
[ANNElementTransition transitionsOf:_plan.elements views:views];
|
|
149
176
|
ANNViewTracks *arrivingTracks = nil;
|
|
150
177
|
ANNViewTracks *leavingTracks = nil;
|
|
151
178
|
if (_plan.enter && _arriving) {
|
|
@@ -190,8 +217,9 @@ static void ANNUpdateRootLayoutOf(UIViewController *node) {
|
|
|
190
217
|
duration:_plan.length
|
|
191
218
|
alphaBefore:_leavingAlpha];
|
|
192
219
|
}
|
|
193
|
-
// The arriving view
|
|
194
|
-
|
|
220
|
+
// The arriving view gets its own alpha back: an `opacity` animation of its tracks shows over it from the start, in
|
|
221
|
+
// the same transaction.
|
|
222
|
+
if (_arriving) {
|
|
195
223
|
_arriving.alpha = _arrivingAlpha;
|
|
196
224
|
}
|
|
197
225
|
if (arrivingTracks.hasTracks) {
|
|
@@ -200,14 +228,26 @@ static void ANNUpdateRootLayoutOf(UIViewController *node) {
|
|
|
200
228
|
if (leavingTracks.hasTracks) {
|
|
201
229
|
[clients addObject:leavingTracks];
|
|
202
230
|
}
|
|
203
|
-
|
|
204
|
-
|
|
231
|
+
// Each element plays on its own: one whose animations fail goes back and stays, the others and the screens go on.
|
|
232
|
+
for (ANNElementTransition *element in elements) {
|
|
233
|
+
[clients addObject:[[ANNIsolatedElement alloc] initWithClient:element name:element.name]];
|
|
234
|
+
}
|
|
235
|
+
for (ANNSharedElementFlight *flight in flights) {
|
|
236
|
+
[clients addObject:[[ANNIsolatedElement alloc] initWithClient:flight name:flight.name]];
|
|
237
|
+
}
|
|
205
238
|
_clients = clients;
|
|
206
239
|
if ([self tilts]) {
|
|
207
240
|
[self orderInDepthIn:container flights:flights];
|
|
208
241
|
}
|
|
209
242
|
__weak ANNTransitionAnimator *weakSelf = self;
|
|
210
243
|
_driver = [[ANNFrameDriver alloc] initWithClients:clients length:_plan.length];
|
|
244
|
+
if (_followsGesture) {
|
|
245
|
+
[_driver startPausedOn:container.layer
|
|
246
|
+
done:^(BOOL finished) {
|
|
247
|
+
[weakSelf complete];
|
|
248
|
+
}];
|
|
249
|
+
return;
|
|
250
|
+
}
|
|
211
251
|
[_driver startWithDone:^{
|
|
212
252
|
[weakSelf complete];
|
|
213
253
|
}];
|
|
@@ -286,8 +326,16 @@ static BOOL ANNSideTilts(ANNViewAnimationOptions *side) {
|
|
|
286
326
|
}
|
|
287
327
|
[_wait cancel];
|
|
288
328
|
_wait = nil;
|
|
329
|
+
// An interactive transition ends at its end state too: UIKit completes only one whose end was chosen.
|
|
330
|
+
if (_followsGesture && !_endChosen) {
|
|
331
|
+
_endChosen = YES;
|
|
332
|
+
[_context finishInteractiveTransition];
|
|
333
|
+
}
|
|
334
|
+
// A stopped clock gets its time back in the commit that removes the animations.
|
|
335
|
+
[CATransaction begin];
|
|
289
336
|
[_driver cancel];
|
|
290
337
|
[self complete];
|
|
338
|
+
[CATransaction commit];
|
|
291
339
|
}
|
|
292
340
|
|
|
293
341
|
@end
|
|
@@ -19,8 +19,8 @@ typedef NS_ENUM(NSInteger, ANNTransitionKind) {
|
|
|
19
19
|
ANNTransitionKindDismiss,
|
|
20
20
|
};
|
|
21
21
|
|
|
22
|
-
/// The screen fade of a transition with elements and no screen animation of its own,
|
|
23
|
-
/// nothing to play.
|
|
22
|
+
/// The screen fade of a transition with elements and no screen animation of its own, of a dismissed popover with
|
|
23
|
+
/// nothing to play, or of any transition while the system's Reduce Motion is on (then nothing else plays).
|
|
24
24
|
typedef NS_ENUM(NSInteger, ANNScreenFade) {
|
|
25
25
|
ANNScreenFadeNone,
|
|
26
26
|
/// The arriving screen from 0 to its alpha.
|
|
@@ -43,6 +43,16 @@ static const NSTimeInterval ANNElementsScreenFade = 0.3;
|
|
|
43
43
|
length = MAX(length, [ANNAnimationRules lengthOfElements:_elements shared:_sharedElements]);
|
|
44
44
|
length = MAX(length, _screenFadeDuration);
|
|
45
45
|
_length = length;
|
|
46
|
+
// With the system's Reduce Motion on, nothing moves: the transition is a fade of the same length, the arriving
|
|
47
|
+
// screen in going forward, the leaving one out otherwise.
|
|
48
|
+
if (UIAccessibilityIsReduceMotionEnabled() && length > 0) {
|
|
49
|
+
_enter = nil;
|
|
50
|
+
_exit = nil;
|
|
51
|
+
_elements = @[];
|
|
52
|
+
_sharedElements = @[];
|
|
53
|
+
_screenFade = _isForward ? ANNScreenFadeArrivingIn : ANNScreenFadeLeavingOut;
|
|
54
|
+
_screenFadeDuration = length;
|
|
55
|
+
}
|
|
46
56
|
}
|
|
47
57
|
return self;
|
|
48
58
|
}
|
|
@@ -48,13 +48,12 @@ static const NSTimeInterval ANNReadyCheckDelay = 0.1;
|
|
|
48
48
|
}
|
|
49
49
|
|
|
50
50
|
- (BOOL)targetsAreFound {
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
arrivingRoot:arrivingRoot];
|
|
51
|
+
ANNTransitionViews *views = [[ANNTransitionViews alloc] initWithPairs:_plan.sharedElements
|
|
52
|
+
elements:_plan.elements
|
|
53
|
+
fromNode:_plan.fromNode
|
|
54
|
+
toNode:_plan.toNode];
|
|
55
|
+
return [ANNSharedElementFlight allTargetsFound:_plan.sharedElements views:views] &&
|
|
56
|
+
[ANNElementTransition allFound:_plan.elements views:views];
|
|
58
57
|
}
|
|
59
58
|
|
|
60
59
|
- (BOOL)isReady {
|
|
@@ -1,5 +1,10 @@
|
|
|
1
|
+
#import "ANNFrameDriver.h"
|
|
1
2
|
#import <UIKit/UIKit.h>
|
|
2
3
|
|
|
4
|
+
@class ANNElementTransitionOptions;
|
|
5
|
+
@class ANNSharedElementTransitionOptions;
|
|
6
|
+
@class Text;
|
|
7
|
+
|
|
3
8
|
NS_ASSUME_NONNULL_BEGIN
|
|
4
9
|
|
|
5
10
|
/// Finds the React views of the elements of a transition by their `nativeID`: depth first, the first match, in the
|
|
@@ -21,6 +26,58 @@ NS_ASSUME_NONNULL_BEGIN
|
|
|
21
26
|
+ (nullable UIView *)viewWithNativeID:(nullable NSString *)nativeID
|
|
22
27
|
inNode:(nullable UIViewController *)node;
|
|
23
28
|
|
|
29
|
+
/// The views with the `nativeID`s of `nativeIDs` in `root` and its subviews, in one walk: for each id the view
|
|
30
|
+
/// `viewWithNativeID:inView:` finds; an id no view has is left out. The walk stops once every id is found.
|
|
31
|
+
+ (NSDictionary<NSString *, UIView *> *)viewsWithNativeIDs:(NSSet<NSString *> *)nativeIDs
|
|
32
|
+
inView:(nullable UIView *)root;
|
|
33
|
+
|
|
34
|
+
@end
|
|
35
|
+
|
|
36
|
+
/// The views of a transition's elements in its two screens: each screen is walked once, at its first lookup, for the
|
|
37
|
+
/// ids looked for there — the leaving one for the pairs' `fromId`s and the elements' ids, the arriving one for the
|
|
38
|
+
/// pairs' `toId`s and the elements' ids the leaving one doesn't have. A lookup finds what
|
|
39
|
+
/// `+[ANNElementFinder viewWithNativeID:inView:]` finds in that screen as it was at its walk. Main queue.
|
|
40
|
+
@interface ANNTransitionViews : NSObject
|
|
41
|
+
|
|
42
|
+
- (instancetype)initWithPairs:(nullable NSArray<ANNSharedElementTransitionOptions *> *)pairs
|
|
43
|
+
elements:(nullable NSArray<ANNElementTransitionOptions *> *)elements
|
|
44
|
+
fromNode:(nullable UIViewController *)fromNode
|
|
45
|
+
toNode:(nullable UIViewController *)toNode NS_DESIGNATED_INITIALIZER;
|
|
46
|
+
- (instancetype)init NS_UNAVAILABLE;
|
|
47
|
+
+ (instancetype)new NS_UNAVAILABLE;
|
|
48
|
+
|
|
49
|
+
/// The React views of the screens the elements are looked for in.
|
|
50
|
+
@property(nonatomic, strong, readonly, nullable) UIView *leavingRoot;
|
|
51
|
+
@property(nonatomic, strong, readonly, nullable) UIView *arrivingRoot;
|
|
52
|
+
|
|
53
|
+
/// The view with `nativeID` in the leaving screen; nil when none has it or the id isn't one of the transition's.
|
|
54
|
+
- (nullable UIView *)leavingViewWithNativeID:(nullable NSString *)nativeID;
|
|
55
|
+
|
|
56
|
+
/// The view with `nativeID` in the arriving screen; nil when none has it or the id isn't one of the transition's.
|
|
57
|
+
- (nullable UIView *)arrivingViewWithNativeID:(nullable NSString *)nativeID;
|
|
58
|
+
|
|
59
|
+
@end
|
|
60
|
+
|
|
61
|
+
/// The `nativeID` an element's option holds; nil when it holds none (not a string, an empty one).
|
|
62
|
+
FOUNDATION_EXPORT NSString *_Nullable ANNNativeIDOf(Text *_Nullable value);
|
|
63
|
+
|
|
64
|
+
/// The isolation of every element of the core's transitions: `work`, a step of the element named `element` (its
|
|
65
|
+
/// `nativeID`, or a pair's two), runs; an exception in it skips that element only — one line in the log
|
|
66
|
+
/// (`ANNElementSkipped`), and NO — while the rest of the transition plays and its command completes.
|
|
67
|
+
FOUNDATION_EXPORT BOOL ANNElementStep(NSString *element, NS_NOESCAPE dispatch_block_t work);
|
|
68
|
+
|
|
69
|
+
/// The line in the log for the element named `element`, skipped for `reason`: it shows and hides with its screen.
|
|
70
|
+
FOUNDATION_EXPORT void ANNElementSkipped(NSString *element, NSString *reason);
|
|
71
|
+
|
|
72
|
+
/// An element's animations, made in `ANNElementStep`: when making them fails, the element's values go back
|
|
73
|
+
/// (`-restore`) and it doesn't move; the rest of the transition plays.
|
|
74
|
+
@interface ANNIsolatedElement : NSObject <ANNFrameClient>
|
|
75
|
+
|
|
76
|
+
- (instancetype)initWithClient:(id<ANNFrameClient>)client
|
|
77
|
+
name:(NSString *)name NS_DESIGNATED_INITIALIZER;
|
|
78
|
+
- (instancetype)init NS_UNAVAILABLE;
|
|
79
|
+
+ (instancetype)new NS_UNAVAILABLE;
|
|
80
|
+
|
|
24
81
|
@end
|
|
25
82
|
|
|
26
83
|
NS_ASSUME_NONNULL_END
|