@apexnative/navigation 1.0.0-alpha.0 → 1.0.0-alpha.10
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/ApexNavigation.podspec +2 -1
- package/CHANGELOG.md +128 -0
- package/README.md +147 -51
- package/android/CLAUDE.md +78 -25
- package/android/CORE.md +49 -25
- package/android/RECIPES.md +13 -6
- package/android/consumer-rules.pro +6 -0
- package/android/src/main/java/dev/apexnative/navigation/NavigationActivity.kt +85 -10
- package/android/src/main/java/dev/apexnative/navigation/NavigationApplication.kt +34 -13
- package/android/src/main/java/dev/apexnative/navigation/layout/LayoutChecks.kt +5 -1
- package/android/src/main/java/dev/apexnative/navigation/layout/LayoutNode.kt +6 -2
- package/android/src/main/java/dev/apexnative/navigation/nativescreen/NativeScreenContext.kt +2 -2
- package/android/src/main/java/dev/apexnative/navigation/options/AnimationsOptions.kt +2 -2
- package/android/src/main/java/dev/apexnative/navigation/options/BottomTabOptions.kt +1 -1
- package/android/src/main/java/dev/apexnative/navigation/options/BottomTabsOptions.kt +13 -8
- package/android/src/main/java/dev/apexnative/navigation/options/ButtonMenuOptions.kt +2 -2
- package/android/src/main/java/dev/apexnative/navigation/options/ButtonOptions.kt +3 -3
- package/android/src/main/java/dev/apexnative/navigation/options/HardwareBackButtonOptions.kt +9 -1
- package/android/src/main/java/dev/apexnative/navigation/options/LargeTitleOptions.kt +1 -1
- package/android/src/main/java/dev/apexnative/navigation/options/LayoutAnimation.kt +1 -1
- package/android/src/main/java/dev/apexnative/navigation/options/OptionKey.kt +18 -0
- package/android/src/main/java/dev/apexnative/navigation/options/OptionPaths.kt +91 -0
- package/android/src/main/java/dev/apexnative/navigation/options/OptionsCache.kt +8 -4
- package/android/src/main/java/dev/apexnative/navigation/options/SheetOptions.kt +7 -4
- package/android/src/main/java/dev/apexnative/navigation/options/SideMenuOptions.kt +6 -1
- package/android/src/main/java/dev/apexnative/navigation/options/StackAnimationOptions.kt +40 -2
- package/android/src/main/java/dev/apexnative/navigation/options/StatusBarOptions.kt +7 -3
- package/android/src/main/java/dev/apexnative/navigation/options/TitleOptions.kt +2 -2
- package/android/src/main/java/dev/apexnative/navigation/options/TopBarAppearanceOptions.kt +1 -1
- package/android/src/main/java/dev/apexnative/navigation/options/TopBarOptions.kt +16 -7
- package/android/src/main/java/dev/apexnative/navigation/options/UserChoices.kt +159 -0
- package/android/src/main/java/dev/apexnative/navigation/react/CommandAnswer.kt +29 -36
- package/android/src/main/java/dev/apexnative/navigation/react/CommandContract.kt +59 -0
- package/android/src/main/java/dev/apexnative/navigation/react/ContentHeights.kt +95 -0
- package/android/src/main/java/dev/apexnative/navigation/react/ContentMounts.kt +66 -0
- package/android/src/main/java/dev/apexnative/navigation/react/ErrorTexts.kt +75 -60
- package/android/src/main/java/dev/apexnative/navigation/react/Hinge.kt +35 -23
- package/android/src/main/java/dev/apexnative/navigation/react/NavigationTurboModule.kt +12 -7
- package/android/src/main/java/dev/apexnative/navigation/react/OptionsCommands.kt +42 -4
- package/android/src/main/java/dev/apexnative/navigation/react/PendingCalls.kt +48 -0
- package/android/src/main/java/dev/apexnative/navigation/react/ReactView.kt +54 -20
- package/android/src/main/java/dev/apexnative/navigation/react/ReloadCoordinator.kt +7 -6
- package/android/src/main/java/dev/apexnative/navigation/react/ScreenEnvironment.kt +177 -0
- package/android/src/main/java/dev/apexnative/navigation/react/ScreenRegions.kt +19 -50
- package/android/src/main/java/dev/apexnative/navigation/react/ScrollEvents.kt +49 -128
- package/android/src/main/java/dev/apexnative/navigation/react/events/AppearanceDispatcher.kt +50 -81
- package/android/src/main/java/dev/apexnative/navigation/react/events/EventContract.kt +226 -0
- package/android/src/main/java/dev/apexnative/navigation/react/events/EventEmitter.kt +135 -94
- package/android/src/main/java/dev/apexnative/navigation/react/events/NavigationState.kt +154 -0
- package/android/src/main/java/dev/apexnative/navigation/react/events/ScreenAppearance.kt +0 -6
- package/android/src/main/java/dev/apexnative/navigation/safearea/SafeAreaView.kt +12 -10
- package/android/src/main/java/dev/apexnative/navigation/slots/SlotContainers.kt +10 -7
- package/android/src/main/java/dev/apexnative/navigation/slots/SlotScreenView.kt +39 -19
- package/android/src/main/java/dev/apexnative/navigation/slots/SlotView.kt +16 -4
- package/android/src/main/java/dev/apexnative/navigation/slots/SlotViews.kt +40 -0
- package/android/src/main/java/dev/apexnative/navigation/utils/ImageKey.kt +66 -0
- package/android/src/main/java/dev/apexnative/navigation/utils/ImageLoader.kt +7 -89
- package/android/src/main/java/dev/apexnative/navigation/utils/ImageRequests.kt +76 -0
- package/android/src/main/java/dev/apexnative/navigation/utils/MaterialTheme.kt +5 -6
- package/android/src/main/java/dev/apexnative/navigation/utils/OptionImages.kt +262 -0
- package/android/src/main/java/dev/apexnative/navigation/utils/SystemAnimations.kt +36 -0
- package/android/src/main/java/dev/apexnative/navigation/utils/UiUtils.kt +3 -3
- package/android/src/main/java/dev/apexnative/navigation/utils/ViewController.kt +3 -1
- package/android/src/main/java/dev/apexnative/navigation/utils/ViewExtensions.kt +0 -13
- package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/arrangement/ArrangementController.kt +10 -7
- package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/arrangement/SecondaryScreenPresenter.kt +13 -5
- package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/bottomtabs/AppliedTabCalls.kt +49 -0
- package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/bottomtabs/BottomTabsCollapseBehavior.kt +5 -3
- package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/bottomtabs/BottomTabsController.kt +108 -34
- package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/bottomtabs/BottomTabsPresenter.kt +25 -24
- package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/bottomtabs/CustomTabRowGeometry.kt +22 -0
- package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/bottomtabs/TabItems.kt +3 -3
- package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/bottomtabs/TabsRoom.kt +0 -5
- package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/component/ComponentPresenter.kt +28 -7
- package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/component/ComponentViewController.kt +12 -9
- package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/component/ContentReadiness.kt +2 -2
- package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/component/RenderWait.kt +27 -7
- package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/component/ScreenFrame.kt +1 -1
- package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/component/ScreenReadiness.kt +103 -56
- package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/component/ScreenSafeArea.kt +29 -11
- package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/externalcomponent/ExternalComponentViewController.kt +2 -6
- package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/modal/ModalAnimations.kt +22 -24
- package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/modal/ModalCoordinator.kt +109 -21
- package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/modal/ModalRecord.kt +21 -6
- package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/modal/ModalSheet.kt +476 -73
- package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/modal/ModalViews.kt +57 -25
- package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/modal/SheetBack.kt +42 -0
- package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/modal/SheetStops.kt +83 -0
- package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/navigator/BackCallbackCheck.kt +50 -0
- package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/navigator/BackCallbackState.kt +49 -14
- package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/navigator/Navigator.kt +71 -12
- package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/navigator/RootCoordinator.kt +37 -11
- package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/overlay/OverlayCoordinator.kt +10 -8
- package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/parent/Capabilities.kt +11 -4
- package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/parent/ContainerBackground.kt +3 -3
- package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/parent/ParentController.kt +6 -6
- package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/sidemenu/SideMenuController.kt +42 -9
- package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/sidemenu/SideMenuMotion.kt +19 -8
- package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/sidemenu/SideMenuPresenter.kt +16 -7
- package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/sidemenu/SideMenuRules.kt +43 -4
- package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/splitview/SplitPanes.kt +23 -0
- package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/splitview/SplitViewController.kt +77 -17
- package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/stack/BackPreview.kt +315 -0
- package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/stack/PreparedFrame.kt +3 -3
- package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/stack/StackCommands.kt +30 -20
- package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/stack/StackController.kt +216 -18
- package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/stack/StackDisplay.kt +26 -1
- package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/stack/StackQueue.kt +149 -41
- package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/stack/StackTransitions.kt +26 -8
- package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/stack/StackViews.kt +115 -6
- package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/stack/fab/FabMotion.kt +142 -0
- package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/stack/fab/FabPresenter.kt +222 -48
- package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/stack/search/ScreenSearch.kt +3 -5
- package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/stack/search/StackSearchPresenter.kt +30 -34
- package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/stack/topbar/BarComponents.kt +5 -51
- package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/stack/topbar/BarRowTransition.kt +3 -2
- package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/stack/topbar/ButtonPlaces.kt +11 -5
- package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/stack/topbar/MenuChecks.kt +13 -56
- package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/stack/topbar/TopBarPresenter.kt +219 -54
- package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/stack/topbar/TopBarVisibility.kt +9 -2
- package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/viewcontroller/ScrollEventListener.kt +6 -9
- package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/viewcontroller/ViewController.kt +75 -21
- package/android/src/main/java/dev/apexnative/navigation/views/animations/AnimationLayer.kt +73 -0
- package/android/src/main/java/dev/apexnative/navigation/views/animations/Curves.kt +29 -11
- package/android/src/main/java/dev/apexnative/navigation/views/animations/ValueInterpolation.kt +14 -0
- package/android/src/main/java/dev/apexnative/navigation/views/bottomtabs/BottomTabs.kt +9 -7
- package/android/src/main/java/dev/apexnative/navigation/views/bottomtabs/BottomTabsLayout.kt +61 -2
- package/android/src/main/java/dev/apexnative/navigation/views/bottomtabs/CustomBottomTabItemView.kt +0 -5
- package/android/src/main/java/dev/apexnative/navigation/views/bottomtabs/CustomTabRow.kt +72 -10
- package/android/src/main/java/dev/apexnative/navigation/views/element/ElementStep.kt +31 -0
- package/android/src/main/java/dev/apexnative/navigation/views/element/ElementTransitions.kt +143 -135
- package/android/src/main/java/dev/apexnative/navigation/views/element/TargetsWait.kt +13 -5
- package/android/src/main/java/dev/apexnative/navigation/views/element/TransitionLayer.kt +37 -112
- package/android/src/main/java/dev/apexnative/navigation/views/element/TransitionTargets.kt +9 -6
- package/android/src/main/java/dev/apexnative/navigation/views/element/TransitionViews.kt +100 -0
- package/android/src/main/java/dev/apexnative/navigation/views/element/animators/ElementPictures.kt +112 -4
- package/android/src/main/java/dev/apexnative/navigation/views/element/animators/FlightGeometry.kt +346 -36
- package/android/src/main/java/dev/apexnative/navigation/views/element/animators/ImageMorph.kt +199 -0
- package/android/src/main/java/dev/apexnative/navigation/views/element/animators/SharedAnimatorFactory.kt +56 -41
- package/android/src/main/java/dev/apexnative/navigation/views/element/animators/TextMorph.kt +176 -0
- package/android/src/main/java/dev/apexnative/navigation/views/element/animators/ViewMorph.kt +108 -0
- package/android/src/main/java/dev/apexnative/navigation/views/sidemenu/SideMenuView.kt +12 -3
- package/android/src/main/java/dev/apexnative/navigation/views/stack/ScreenEdge.kt +45 -0
- package/android/src/main/java/dev/apexnative/navigation/views/stack/StackLayout.kt +140 -1
- package/android/src/main/java/dev/apexnative/navigation/views/stack/fab/Fab.kt +14 -10
- package/android/src/main/java/dev/apexnative/navigation/views/stack/fab/FabCopy.kt +85 -0
- package/android/src/main/java/dev/apexnative/navigation/views/stack/fab/FabMenu.kt +13 -0
- package/android/src/main/java/dev/apexnative/navigation/views/stack/topbar/TitleBar.kt +5 -17
- package/android/src/main/java/dev/apexnative/navigation/views/stack/topbar/TopBar.kt +73 -34
- package/android/src/main/java/dev/apexnative/navigation/views/stack/topbar/titlebar/BarButtonComponentCell.kt +6 -6
- package/android/src/main/java/dev/apexnative/navigation/views/stack/topbar/titlebar/BarButtonView.kt +113 -0
- package/android/src/main/java/dev/apexnative/navigation/views/stack/topbar/titlebar/BarMenu.kt +219 -0
- package/android/src/main/java/dev/apexnative/navigation/views/stack/topbar/titlebar/ButtonBar.kt +125 -178
- package/android/src/main/java/dev/apexnative/navigation/views/stack/topbar/titlebar/ButtonMenus.kt +34 -64
- package/android/src/main/java/dev/apexnative/navigation/views/stack/topbar/titlebar/ButtonRow.kt +216 -0
- package/android/src/main/jni/ANNContentHeights.cpp +82 -0
- package/android/src/main/res/drawable/apex_navigation_ic_arrow_right.xml +14 -0
- package/android/src/main/res/layout/apex_navigation_menu_header.xml +19 -0
- package/android/src/main/res/layout/apex_navigation_menu_item.xml +68 -0
- package/android/src/main/res/values/styles.xml +1 -1
- package/android/src/main/res/values-night/styles.xml +1 -1
- package/cli/app.js +1 -1
- package/cli/doctor/checks/app.js +77 -14
- package/cli/doctor/checks/splash.js +4 -22
- package/cli/migrate/native.js +18 -0
- package/cli/project.js +10 -2
- package/cli/setup/index.js +18 -0
- package/cli/setup/source.js +2 -1
- package/cli/setup/steps/appDelegate.js +66 -11
- package/cli/setup/steps/mainApplication.js +134 -19
- package/cli/setup/steps/metro.js +46 -0
- package/cli/setup/steps/sceneDelegate.js +108 -0
- package/cli/splash/index.js +3 -1
- package/cli/upgrade/changelog.js +2 -2
- package/docs-md/architecture/native-screens.md +4 -0
- package/docs-md/architecture/theme-and-context.md +131 -12
- package/docs-md/architecture/transitions.md +58 -12
- package/docs-md/containers/modals.md +8 -4
- package/docs-md/containers/overlays.md +3 -1
- package/docs-md/containers/side-menu.md +19 -2
- package/docs-md/containers/tabs.md +5 -1
- package/docs-md/flows/bottom-sheets.md +4 -2
- package/docs-md/flows/forms-in-a-modal.md +1 -1
- package/docs-md/fundamentals/screens-and-props.md +9 -1
- package/docs-md/fundamentals/starting-the-app.md +1 -1
- package/docs-md/guides/cli.md +4 -3
- package/docs-md/guides/deep-links.md +15 -33
- package/docs-md/help/glossary.md +4 -4
- package/docs-md/help/troubleshooting.md +44 -6
- package/docs-md/index.json +57 -1
- package/docs-md/migration/from-expo-router.md +1 -1
- package/docs-md/migration/from-react-native-navigation.md +9 -3
- package/docs-md/migration/from-react-navigation.md +2 -2
- package/docs-md/screen-ui/back-and-gestures.md +46 -2
- package/docs-md/screen-ui/bar-buttons.md +5 -5
- package/docs-md/screen-ui/search.md +1 -1
- package/docs-md/screen-ui/system-ui.md +17 -12
- package/docs-md/screen-ui/toolbar-and-fab.md +4 -2
- package/docs-md/screen-ui/top-bar.md +8 -4
- package/docs-md/start/installation.md +21 -3
- package/ios/Animations/ANNFrameDriver.h +55 -15
- package/ios/Animations/ANNFrameDriver.mm +216 -60
- package/ios/Animations/ANNTransitionAnimator.h +26 -5
- package/ios/Animations/ANNTransitionAnimator.mm +61 -13
- package/ios/Animations/ANNTransitionPlan.h +2 -2
- package/ios/Animations/ANNTransitionPlan.mm +10 -0
- package/ios/Animations/ANNTransitionWait.mm +6 -7
- package/ios/Animations/Elements/ANNElementFinder.h +57 -0
- package/ios/Animations/Elements/ANNElementFinder.mm +174 -2
- package/ios/Animations/Elements/ANNElementTransition.h +10 -8
- package/ios/Animations/Elements/ANNElementTransition.mm +19 -21
- package/ios/Animations/Elements/ANNSharedElementFlight.h +16 -11
- package/ios/Animations/Elements/ANNSharedElementFlight.mm +308 -69
- package/ios/Animations/Interpolators/ANNInterpolate.h +2 -30
- package/ios/Animations/Interpolators/ANNTransformParts.h +48 -0
- package/ios/Animations/Interpolators/ANNTransformParts.mm +507 -0
- package/ios/Animations/Interpolators/ANNViewTracks.h +9 -6
- package/ios/Animations/Interpolators/ANNViewTracks.mm +100 -30
- package/ios/CLAUDE.md +60 -24
- package/ios/CORE.md +44 -34
- package/ios/Contract/ANNCommandAnswer.h +13 -5
- package/ios/Contract/ANNCommandAnswer.mm +40 -32
- package/ios/Contract/ANNCommandContract.h +15 -0
- package/ios/Contract/ANNCommandContract.mm +78 -0
- package/ios/Contract/ANNCommandRunner.h +10 -9
- package/ios/Contract/ANNCommandRunner.mm +22 -28
- package/ios/Contract/ANNErrorTexts.h +6 -2
- package/ios/Contract/ANNErrorTexts.mm +18 -10
- package/ios/Contract/ANNLayoutNode.h +3 -3
- package/ios/Contract/ANNLayoutReader.h +3 -3
- package/ios/Core/ANNAppDelegate.mm +0 -2
- package/ios/Core/ANNAppearanceDispatcher.h +5 -4
- package/ios/Core/ANNAppearanceDispatcher.mm +12 -1
- package/ios/Core/ANNDeepLinkQueue.h +22 -2
- package/ios/Core/ANNDeepLinkQueue.mm +121 -14
- package/ios/Core/ANNErrorHandler.h +9 -4
- package/ios/Core/ANNErrorHandler.mm +20 -2
- package/ios/Core/ANNEventContract.h +246 -0
- package/ios/Core/ANNEventContract.mm +225 -0
- package/ios/Core/ANNEventEmitter.h +6 -2
- package/ios/Core/ANNEventEmitter.mm +117 -80
- package/ios/Core/ANNHinge.h +6 -0
- package/ios/Core/ANNHinge.mm +15 -4
- package/ios/Core/ANNJavaScriptCalls.h +33 -0
- package/ios/Core/ANNJavaScriptCalls.mm +52 -0
- package/ios/Core/ANNLayoutProtocol.h +5 -5
- package/ios/Core/ANNNavigationState.h +7 -5
- package/ios/Core/ANNNavigationState.mm +8 -7
- package/ios/Core/ANNNodeHelper.h +32 -12
- package/ios/Core/ANNNodeHelper.mm +100 -3
- package/ios/Core/ANNParking.h +5 -4
- package/ios/Core/ANNReloadCoordinator.mm +5 -12
- package/ios/Core/ANNRenderWait.h +20 -6
- package/ios/Core/ANNRenderWait.mm +143 -56
- package/ios/Core/ANNSceneDelegate.mm +25 -15
- package/ios/Core/ANNSystemUI.h +3 -2
- package/ios/Core/ANNSystemUI.mm +7 -0
- package/ios/Core/ANNUtils.h +7 -0
- package/ios/Core/ANNUtils.mm +10 -0
- package/ios/Core/ApexNavigation+Internal.h +1 -1
- package/ios/Core/ApexNavigation.mm +7 -6
- package/ios/Core/UIViewController+LayoutProtocol.h +9 -2
- package/ios/Core/UIViewController+LayoutProtocol.mm +8 -0
- package/ios/Layouts/Arrangement/ANNArrangementState.h +2 -17
- package/ios/Layouts/Arrangement/ANNArrangementState.mm +0 -38
- package/ios/Layouts/Arrangement/ANNArrangementViewController.mm +10 -8
- package/ios/Layouts/Modal/ANNModalCoordinator.h +1 -1
- package/ios/Layouts/Modal/ANNModalCoordinator.mm +57 -16
- package/ios/Layouts/Modal/ANNModalPresentation.h +8 -5
- package/ios/Layouts/Modal/ANNModalPresentation.mm +12 -12
- package/ios/Layouts/Modal/ANNSheetPresenter.mm +83 -1
- package/ios/Layouts/Overlay/ANNOverlayCoordinator.mm +2 -8
- package/ios/Layouts/Root/ANNRootCoordinator.mm +58 -19
- package/ios/Layouts/Root/ANNSplashViewController.h +5 -3
- package/ios/Layouts/Root/ANNSplashViewController.mm +147 -0
- package/ios/Layouts/Screen/ANNComponentPresenter.h +11 -3
- package/ios/Layouts/Screen/ANNComponentPresenter.mm +34 -6
- package/ios/Layouts/Screen/ANNComponentViewController.h +15 -13
- package/ios/Layouts/Screen/ANNComponentViewController.mm +130 -75
- package/ios/Layouts/Screen/ANNNativeScreenContext.mm +7 -5
- package/ios/Layouts/Screen/ANNPreviewInteraction.h +7 -4
- package/ios/Layouts/Screen/ANNPreviewInteraction.mm +72 -10
- package/ios/Layouts/Screen/ANNScreenEnvironment.h +63 -0
- package/ios/Layouts/Screen/ANNScreenEnvironment.mm +181 -0
- package/ios/Layouts/Screen/ANNScreenPlace.h +53 -0
- package/ios/Layouts/Screen/ANNScreenPlace.mm +205 -0
- package/ios/Layouts/Screen/ANNScreenRegions.h +3 -18
- package/ios/Layouts/Screen/ANNScreenRegions.mm +9 -44
- package/ios/Layouts/Screen/ANNScreenSafeArea.h +4 -9
- package/ios/Layouts/Screen/ANNScreenSafeArea.mm +14 -16
- package/ios/Layouts/Screen/ANNScreenSettling.h +32 -0
- package/ios/Layouts/Screen/ANNScreenSettling.mm +137 -0
- package/ios/Layouts/SideMenu/ANNSideMenuTypes.h +8 -0
- package/ios/Layouts/SideMenu/ANNSideMenuViewController.mm +83 -14
- package/ios/Layouts/SplitView/ANNSplitViewCommands.h +3 -2
- package/ios/Layouts/SplitView/ANNSplitViewCommands.mm +105 -39
- package/ios/Layouts/SplitView/ANNSplitViewController.mm +7 -8
- package/ios/Layouts/Stack/ANNPreviewPush.h +7 -6
- package/ios/Layouts/Stack/ANNPreviewPush.mm +142 -27
- package/ios/Layouts/Stack/ANNStackAnimatingDelegate.h +11 -2
- package/ios/Layouts/Stack/ANNStackAnimatingDelegate.mm +14 -7
- package/ios/Layouts/Stack/ANNStackCommands.mm +1 -0
- package/ios/Layouts/Stack/ANNStackController.h +8 -0
- package/ios/Layouts/Stack/ANNStackController.mm +184 -16
- package/ios/Layouts/Stack/ANNStackQueue.h +5 -2
- package/ios/Layouts/Stack/ANNStackQueue.mm +56 -43
- package/ios/Layouts/Stack/ANNSwipePopInteraction.h +26 -0
- package/ios/Layouts/Stack/ANNSwipePopInteraction.mm +185 -0
- package/ios/Layouts/Stack/InteractivePopGestureDelegate.mm +28 -4
- package/ios/Layouts/Stack/UINavigationController+ANNCommands.h +4 -2
- package/ios/Layouts/Stack/UINavigationController+ANNCommands.mm +2 -3
- package/ios/Layouts/Tabs/ANNBottomTabItemBuilder.h +4 -0
- package/ios/Layouts/Tabs/ANNBottomTabItemBuilder.mm +11 -0
- package/ios/Layouts/Tabs/ANNBottomTabsAccessoryView.h +12 -1
- package/ios/Layouts/Tabs/ANNBottomTabsAccessoryView.mm +23 -0
- package/ios/Layouts/Tabs/ANNBottomTabsController.h +3 -0
- package/ios/Layouts/Tabs/ANNBottomTabsController.mm +237 -57
- package/ios/Layouts/Tabs/ANNBottomTabsCustomRow.mm +8 -3
- package/ios/Layouts/Tabs/ANNBottomTabsPresenter.h +6 -2
- package/ios/Layouts/Tabs/ANNBottomTabsPresenter.mm +232 -43
- package/ios/Layouts/Tabs/ANNTabsDesign.h +6 -5
- package/ios/Layouts/Tabs/ANNTabsDesign.mm +9 -1
- package/ios/Layouts/Tabs/UITabBar+utils.h +5 -5
- package/ios/Layouts/Tabs/UITabBar+utils.mm +32 -13
- package/ios/Options/ANNAnimationOptions.h +2 -1
- package/ios/Options/ANNAnimationOptions.mm +1 -1
- package/ios/Options/ANNBottomTabsOptions.h +2 -0
- package/ios/Options/ANNBottomTabsOptions.mm +1 -0
- package/ios/Options/ANNOptions.h +25 -0
- package/ios/Options/ANNOptions.mm +157 -1
- package/ios/Options/ANNOptionsCache.h +7 -6
- package/ios/Options/ANNOptionsReader.mm +108 -0
- package/ios/Options/ANNSearchBarOptions.h +4 -3
- package/ios/Options/ANNSheetOptions.h +4 -1
- package/ios/Options/ANNSideMenuOptions.h +2 -0
- package/ios/Options/ANNSideMenuOptions.mm +2 -0
- package/ios/Options/ANNStackPopAnimationOptions.h +13 -0
- package/ios/Options/ANNStackPopAnimationOptions.mm +11 -0
- package/ios/Options/ANNUserChoice.h +57 -0
- package/ios/Options/ANNUserChoice.mm +44 -0
- package/ios/Options/Params/ANNImageSource.h +61 -0
- package/ios/Options/Params/ANNImageSource.mm +101 -0
- package/ios/Options/Params/ANNOptionImages.h +37 -0
- package/ios/Options/Params/ANNOptionImages.mm +284 -0
- package/ios/Options/Params/ANNParam.h +15 -0
- package/ios/Options/Params/ANNParam.mm +61 -0
- package/ios/Options/Params/Color.h +3 -0
- package/ios/Options/Params/Color.mm +21 -0
- package/ios/Options/Params/ColorParser.h +4 -3
- package/ios/Options/Params/ColorParser.mm +22 -4
- package/ios/Options/Params/Image.h +15 -2
- package/ios/Options/Params/Image.mm +35 -2
- package/ios/Options/Params/ImageParser.h +5 -5
- package/ios/Options/Params/ImageParser.mm +28 -46
- package/ios/Public/ApexNavigation/ANNSceneDelegate.h +3 -0
- package/ios/Public/ApexNavigation/ApexNavigation.h +1 -1
- package/ios/RECIPES.md +13 -6
- package/ios/React/ANNReactView.mm +6 -25
- package/ios/React/ANNSafeAreaViewComponentView.mm +28 -17
- package/ios/React/ANNSurfaceHostingView.h +14 -0
- package/ios/React/ANNSurfaceHostingView.mm +144 -1
- package/ios/React/Slots/ANNSlotComponentView.mm +24 -17
- package/ios/React/Slots/ANNSlotContainers.h +14 -6
- package/ios/React/Slots/ANNSlotContainers.mm +75 -2
- package/ios/React/Slots/ANNSlotHost.mm +1 -3
- package/ios/React/Slots/ANNSlotScreenView.mm +8 -2
- package/ios/TopBar/ANNBackButtonPresenter.mm +6 -5
- package/ios/TopBar/ANNBarAppearance.h +2 -1
- package/ios/TopBar/ANNBarAppearance.mm +111 -30
- package/ios/TopBar/ANNBarBackgroundComponent.mm +16 -0
- package/ios/TopBar/ANNBarButtonComponentView.h +4 -4
- package/ios/TopBar/ANNBarButtonComponentView.mm +1 -1
- package/ios/TopBar/ANNBarButtons.h +14 -8
- package/ios/TopBar/ANNBarButtons.mm +397 -80
- package/ios/TopBar/ANNIconButtonImage.h +1 -0
- package/ios/TopBar/ANNIconButtonImage.mm +34 -1
- package/ios/TopBar/ANNLargeTitlePresenter.h +13 -0
- package/ios/TopBar/ANNLargeTitlePresenter.mm +50 -7
- package/ios/TopBar/ANNMainList.h +3 -0
- package/ios/TopBar/ANNMainList.mm +4 -0
- package/ios/TopBar/ANNScrollEdgeEffects.h +22 -6
- package/ios/TopBar/ANNScrollEdgeEffects.mm +123 -16
- package/ios/TopBar/ANNSearchPresenter.mm +172 -21
- package/ios/TopBar/ANNSearchResultsViewController.mm +29 -6
- package/ios/TopBar/ANNTopBarPresenter.h +8 -2
- package/ios/TopBar/ANNTopBarPresenter.mm +155 -33
- package/ios/TurboModules/ANNTurboEventEmitter.mm +4 -35
- package/ios/TurboModules/ANNTurboModule.mm +104 -33
- package/ios/cpp/react/renderer/components/ApexNavigationSpec/ANNSlotState.cpp +20 -0
- package/ios/cpp/react/renderer/components/ApexNavigationSpec/ANNSlotState.h +5 -14
- package/lib/module/ARCHITECTURE.md +40 -27
- package/lib/module/adapters/NativeANNTurboModule.js.map +1 -1
- package/lib/module/api/app/AppRegistry.js +14 -2
- package/lib/module/api/app/AppRegistry.js.map +1 -1
- package/lib/module/api/app/createNavigation.js +190 -66
- package/lib/module/api/app/createNavigation.js.map +1 -1
- package/lib/module/api/commands/commands.js +54 -6
- package/lib/module/api/commands/commands.js.map +1 -1
- package/lib/module/api/events/navigationEvents.js +6 -2
- package/lib/module/api/events/navigationEvents.js.map +1 -1
- package/lib/module/api/hooks/useNavigation.js +8 -3
- package/lib/module/api/hooks/useNavigation.js.map +1 -1
- package/lib/module/api/hooks/useSafeAreaInsets.js +4 -3
- package/lib/module/api/hooks/useSafeAreaInsets.js.map +1 -1
- package/lib/module/api/linking/dispatchedLinks.js +23 -0
- package/lib/module/api/linking/dispatchedLinks.js.map +1 -0
- package/lib/module/api/linking/linking.js +11 -0
- package/lib/module/api/linking/linking.js.map +1 -1
- package/lib/module/api/navigation.js.map +1 -1
- package/lib/module/api/options/OptionsChain.js +2 -2
- package/lib/module/api/screens/defineScreen.js +45 -3
- package/lib/module/api/screens/defineScreen.js.map +1 -1
- package/lib/module/api/screens/nativeScreens.js +31 -6
- package/lib/module/api/screens/nativeScreens.js.map +1 -1
- package/lib/module/api/screens/registerScreens.js +193 -35
- package/lib/module/api/screens/registerScreens.js.map +1 -1
- package/lib/module/api/theme/theme.js +5 -0
- package/lib/module/api/theme/theme.js.map +1 -1
- package/lib/module/engine/commands.js +51 -9
- package/lib/module/engine/commands.js.map +1 -1
- package/lib/module/engine/layout.js +20 -11
- package/lib/module/engine/layout.js.map +1 -1
- package/lib/module/engine/nativeScreens.js +9 -0
- package/lib/module/engine/nativeScreens.js.map +1 -1
- package/lib/module/engine/options.js +49 -15
- package/lib/module/engine/options.js.map +1 -1
- package/lib/module/engine/optionsChange.js +102 -0
- package/lib/module/engine/optionsChange.js.map +1 -0
- package/lib/module/engine/places.js +52 -7
- package/lib/module/engine/places.js.map +1 -1
- package/lib/module/engine/props.js +30 -1
- package/lib/module/engine/props.js.map +1 -1
- package/lib/module/engine/refresh.js +85 -0
- package/lib/module/engine/refresh.js.map +1 -0
- package/lib/module/engine/rememberedOptions.js +61 -1
- package/lib/module/engine/rememberedOptions.js.map +1 -1
- package/lib/module/engine/screens.js +77 -16
- package/lib/module/engine/screens.js.map +1 -1
- package/lib/module/interfaces/contract/commands.json +101 -0
- package/lib/module/interfaces/contract/errors.json +275 -0
- package/lib/typescript/adapters/NativeANNTurboModule.d.ts +12 -2
- package/lib/typescript/adapters/NativeANNTurboModule.d.ts.map +1 -1
- package/lib/typescript/api/app/AppRegistry.d.ts.map +1 -1
- package/lib/typescript/api/app/createNavigation.d.ts +8 -3
- package/lib/typescript/api/app/createNavigation.d.ts.map +1 -1
- package/lib/typescript/api/commands/commands.d.ts.map +1 -1
- package/lib/typescript/api/commands/presentation.d.ts +4 -3
- package/lib/typescript/api/commands/presentation.d.ts.map +1 -1
- package/lib/typescript/api/events/navigationEvents.d.ts +3 -3
- package/lib/typescript/api/events/navigationEvents.d.ts.map +1 -1
- package/lib/typescript/api/hooks/useNavigation.d.ts +1 -1
- package/lib/typescript/api/hooks/useNavigation.d.ts.map +1 -1
- package/lib/typescript/api/hooks/useSafeAreaInsets.d.ts +4 -3
- package/lib/typescript/api/hooks/useSafeAreaInsets.d.ts.map +1 -1
- package/lib/typescript/api/index.d.ts +1 -1
- package/lib/typescript/api/index.d.ts.map +1 -1
- package/lib/typescript/api/linking/dispatchedLinks.d.ts +7 -0
- package/lib/typescript/api/linking/dispatchedLinks.d.ts.map +1 -0
- package/lib/typescript/api/linking/linking.d.ts +8 -0
- package/lib/typescript/api/linking/linking.d.ts.map +1 -1
- package/lib/typescript/api/navigation.d.ts +4 -1
- package/lib/typescript/api/navigation.d.ts.map +1 -1
- package/lib/typescript/api/options/OptionsChain.d.ts +2 -2
- package/lib/typescript/api/screens/defineScreen.d.ts +23 -4
- package/lib/typescript/api/screens/defineScreen.d.ts.map +1 -1
- package/lib/typescript/api/screens/nativeScreens.d.ts +8 -1
- package/lib/typescript/api/screens/nativeScreens.d.ts.map +1 -1
- package/lib/typescript/api/screens/registerScreens.d.ts.map +1 -1
- package/lib/typescript/api/theme/theme.d.ts +2 -0
- package/lib/typescript/api/theme/theme.d.ts.map +1 -1
- package/lib/typescript/engine/commands.d.ts +5 -0
- package/lib/typescript/engine/commands.d.ts.map +1 -1
- package/lib/typescript/engine/layout.d.ts.map +1 -1
- package/lib/typescript/engine/nativeScreens.d.ts +5 -0
- package/lib/typescript/engine/nativeScreens.d.ts.map +1 -1
- package/lib/typescript/engine/options.d.ts +5 -2
- package/lib/typescript/engine/options.d.ts.map +1 -1
- package/lib/typescript/engine/optionsChange.d.ts +28 -0
- package/lib/typescript/engine/optionsChange.d.ts.map +1 -0
- package/lib/typescript/engine/places.d.ts +7 -2
- package/lib/typescript/engine/places.d.ts.map +1 -1
- package/lib/typescript/engine/props.d.ts +8 -1
- package/lib/typescript/engine/props.d.ts.map +1 -1
- package/lib/typescript/engine/refresh.d.ts +35 -0
- package/lib/typescript/engine/refresh.d.ts.map +1 -0
- package/lib/typescript/engine/rememberedOptions.d.ts +13 -0
- package/lib/typescript/engine/rememberedOptions.d.ts.map +1 -1
- package/lib/typescript/engine/screens.d.ts +27 -6
- package/lib/typescript/engine/screens.d.ts.map +1 -1
- package/lib/typescript/interfaces/ComponentEvents.d.ts +4 -4
- package/lib/typescript/interfaces/ComponentEvents.d.ts.map +1 -1
- package/lib/typescript/interfaces/Events.d.ts +28 -10
- package/lib/typescript/interfaces/Events.d.ts.map +1 -1
- package/lib/typescript/interfaces/Options.d.ts +1 -1
- package/lib/typescript/interfaces/Options.d.ts.map +1 -1
- package/lib/typescript/interfaces/options/animations.d.ts +80 -22
- package/lib/typescript/interfaces/options/animations.d.ts.map +1 -1
- package/lib/typescript/interfaces/options/bottomTabs.d.ts +21 -7
- package/lib/typescript/interfaces/options/bottomTabs.d.ts.map +1 -1
- package/lib/typescript/interfaces/options/buttons.d.ts +23 -15
- package/lib/typescript/interfaces/options/buttons.d.ts.map +1 -1
- package/lib/typescript/interfaces/options/modals.d.ts +34 -26
- package/lib/typescript/interfaces/options/modals.d.ts.map +1 -1
- package/lib/typescript/interfaces/options/sideMenu.d.ts +23 -6
- package/lib/typescript/interfaces/options/sideMenu.d.ts.map +1 -1
- package/lib/typescript/interfaces/options/stack.d.ts +17 -3
- package/lib/typescript/interfaces/options/stack.d.ts.map +1 -1
- package/lib/typescript/interfaces/options/system.d.ts +18 -11
- package/lib/typescript/interfaces/options/system.d.ts.map +1 -1
- package/lib/typescript/interfaces/options/toolbar.d.ts +2 -2
- package/lib/typescript/interfaces/options/topBar.d.ts +68 -38
- package/lib/typescript/interfaces/options/topBar.d.ts.map +1 -1
- package/metro/acceptPlugin.js +57 -0
- package/metro/babelTransformer.js +45 -0
- package/metro/index.js +36 -0
- package/package.json +4 -25
- package/src/ARCHITECTURE.md +40 -27
- package/src/adapters/NativeANNTurboModule.ts +12 -2
- package/src/api/app/AppRegistry.ts +16 -2
- package/src/api/app/createNavigation.ts +203 -69
- package/src/api/commands/commands.ts +48 -7
- package/src/api/commands/presentation.ts +4 -3
- package/src/api/events/navigationEvents.ts +10 -4
- package/src/api/hooks/useNavigation.ts +9 -4
- package/src/api/hooks/useSafeAreaInsets.ts +4 -3
- package/src/api/index.ts +1 -0
- package/src/api/linking/dispatchedLinks.ts +18 -0
- package/src/api/linking/linking.ts +22 -1
- package/src/api/navigation.ts +4 -1
- package/src/api/options/OptionsChain.ts +2 -2
- package/src/api/screens/defineScreen.ts +49 -5
- package/src/api/screens/nativeScreens.ts +40 -4
- package/src/api/screens/registerScreens.tsx +185 -42
- package/src/api/theme/theme.ts +5 -0
- package/src/engine/commands.ts +70 -13
- package/src/engine/layout.ts +27 -11
- package/src/engine/nativeScreens.ts +10 -1
- package/src/engine/options.ts +45 -19
- package/src/engine/optionsChange.ts +107 -0
- package/src/engine/places.ts +65 -7
- package/src/engine/props.ts +30 -1
- package/src/engine/refresh.ts +97 -0
- package/src/engine/rememberedOptions.ts +74 -1
- package/src/engine/screens.tsx +76 -21
- package/src/interfaces/ComponentEvents.ts +4 -4
- package/src/interfaces/Events.ts +29 -10
- package/src/interfaces/Options.ts +1 -0
- package/src/interfaces/contract/commands.json +101 -0
- package/src/interfaces/contract/errors.json +275 -0
- package/src/interfaces/options/animations.ts +81 -22
- package/src/interfaces/options/bottomTabs.ts +21 -7
- package/src/interfaces/options/buttons.ts +23 -15
- package/src/interfaces/options/modals.ts +34 -26
- package/src/interfaces/options/sideMenu.ts +24 -6
- package/src/interfaces/options/stack.ts +17 -3
- package/src/interfaces/options/system.ts +18 -11
- package/src/interfaces/options/toolbar.ts +2 -2
- package/src/interfaces/options/topBar.ts +68 -38
- package/android/src/main/java/dev/apexnative/navigation/react/ArrangementStates.kt +0 -41
- package/android/src/main/java/dev/apexnative/navigation/react/ScreenInsets.kt +0 -69
- package/android/src/main/java/dev/apexnative/navigation/react/events/NavigationStateReporter.kt +0 -62
- package/android/src/main/java/dev/apexnative/navigation/react/events/StateHold.kt +0 -62
- package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/bottomtabs/CustomTabRowPlacer.kt +0 -223
- package/android/src/main/java/dev/apexnative/navigation/views/element/ElementStub.kt +0 -31
- package/android/src/main/java/dev/apexnative/navigation/views/element/animators/ImageMatrixAnimator.kt +0 -138
- package/android/src/main/java/dev/apexnative/navigation/views/element/animators/PlainViewAnimator.kt +0 -88
- package/android/src/main/java/dev/apexnative/navigation/views/element/animators/PropertyAnimatorCreator.kt +0 -33
- package/android/src/main/java/dev/apexnative/navigation/views/element/animators/ReactImageAnimator.kt +0 -66
- package/android/src/main/java/dev/apexnative/navigation/views/element/animators/TextChangeAnimator.kt +0 -179
- package/android/src/main/java/dev/apexnative/navigation/views/element/animators/ViewChangeAnimator.kt +0 -139
- package/ios/Layouts/Screen/ANNScreenInsets.h +0 -30
- package/ios/Layouts/Screen/ANNScreenInsets.mm +0 -68
- package/ios/Layouts/Tabs/ANNTabsPreloadWindow.h +0 -27
- package/ios/Layouts/Tabs/ANNTabsPreloadWindow.mm +0 -55
|
@@ -3,19 +3,25 @@
|
|
|
3
3
|
#import "ANNInterpolate.h"
|
|
4
4
|
#import "ANNSharedElementTransitionOptions.h"
|
|
5
5
|
#import "ANNTrack.h"
|
|
6
|
+
#import "ANNTransformParts.h"
|
|
6
7
|
#import "ANNUtils.h"
|
|
7
8
|
#import <React/RCTViewComponentView.h>
|
|
8
9
|
#import <react/renderer/components/view/ViewProps.h>
|
|
10
|
+
#include <cmath>
|
|
9
11
|
|
|
10
12
|
// How close two rectangles count as the same (points): a visible part that is the whole element needs no mask.
|
|
11
13
|
static const CGFloat ANNSameRectTolerance = 0.5;
|
|
12
14
|
|
|
13
15
|
// One end of a flight: the place, the size, the transform, the corners and the visible part of a React view, in the
|
|
14
|
-
// container's coordinates.
|
|
16
|
+
// container's coordinates. The transform is the whole one the view is drawn with there (its own and its parents'),
|
|
17
|
+
// about its center; once split, its scale goes into the size, the corners and the visible part, so the size the copy
|
|
18
|
+
// shows changes evenly on the way.
|
|
15
19
|
typedef struct {
|
|
16
20
|
CGPoint center;
|
|
17
21
|
CGSize size;
|
|
18
22
|
CATransform3D transform;
|
|
23
|
+
// The transform's parts, which the flight interpolates; their scale is only its sign once the scale is in the size.
|
|
24
|
+
ANNTransformParts parts;
|
|
19
25
|
CGFloat cornerRadius;
|
|
20
26
|
// The part the clipping parents leave visible, in the copy's coordinates, and its corners.
|
|
21
27
|
CGRect visible;
|
|
@@ -23,6 +29,21 @@ typedef struct {
|
|
|
23
29
|
BOOL clipped;
|
|
24
30
|
} ANNFlightEnd;
|
|
25
31
|
|
|
32
|
+
// What the copy shows at one time: its size, center, transform and corners, its two pictures' frames and alphas, and
|
|
33
|
+
// its visible part (in the copy's coordinates) with its corners.
|
|
34
|
+
typedef struct {
|
|
35
|
+
CGSize size;
|
|
36
|
+
CGPoint center;
|
|
37
|
+
CATransform3D transform;
|
|
38
|
+
CGFloat cornerRadius;
|
|
39
|
+
CGRect fromFrame;
|
|
40
|
+
CGRect toFrame;
|
|
41
|
+
CGFloat fromAlpha;
|
|
42
|
+
CGFloat toAlpha;
|
|
43
|
+
CGRect mask;
|
|
44
|
+
CGFloat maskRadius;
|
|
45
|
+
} ANNFlightState;
|
|
46
|
+
|
|
26
47
|
static BOOL ANNIsText(UIView *view) {
|
|
27
48
|
static Class paragraph;
|
|
28
49
|
static dispatch_once_t once;
|
|
@@ -71,12 +92,44 @@ static CGFloat ANNCornerRadiusOf(UIView *view) {
|
|
|
71
92
|
return 0;
|
|
72
93
|
}
|
|
73
94
|
|
|
95
|
+
// The anchor of a layer in the coordinates of its bounds.
|
|
96
|
+
static CGPoint ANNAnchorInBounds(CALayer *layer) {
|
|
97
|
+
CGRect bounds = layer.bounds;
|
|
98
|
+
return CGPointMake(bounds.origin.x + layer.anchorPoint.x * bounds.size.width,
|
|
99
|
+
bounds.origin.y + layer.anchorPoint.y * bounds.size.height);
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
// What takes a point of the layer, counted from its anchor, to the top of its tree: its transform and place, then each
|
|
103
|
+
// superlayer's `sublayerTransform`, transform and place the same way (a layer's transforms turn about its anchor).
|
|
104
|
+
static CATransform3D ANNTransformToTop(CALayer *layer) {
|
|
105
|
+
CATransform3D transform = CATransform3DConcat(
|
|
106
|
+
layer.transform, CATransform3DMakeTranslation(layer.position.x, layer.position.y, 0));
|
|
107
|
+
for (CALayer *parent = layer.superlayer; parent; parent = parent.superlayer) {
|
|
108
|
+
CGPoint anchor = ANNAnchorInBounds(parent);
|
|
109
|
+
transform = CATransform3DConcat(transform,
|
|
110
|
+
CATransform3DMakeTranslation(-anchor.x, -anchor.y, 0));
|
|
111
|
+
transform = CATransform3DConcat(transform, parent.sublayerTransform);
|
|
112
|
+
transform = CATransform3DConcat(transform, parent.transform);
|
|
113
|
+
transform = CATransform3DConcat(
|
|
114
|
+
transform, CATransform3DMakeTranslation(parent.position.x, parent.position.y, 0));
|
|
115
|
+
}
|
|
116
|
+
return transform;
|
|
117
|
+
}
|
|
118
|
+
|
|
74
119
|
static ANNFlightEnd ANNFlightEndOf(UIView *view, UIView *screenRoot, UIView *container) {
|
|
75
120
|
ANNFlightEnd end;
|
|
76
121
|
CALayer *layer = view.layer;
|
|
77
122
|
end.size = layer.bounds.size;
|
|
78
|
-
|
|
79
|
-
|
|
123
|
+
// From the view's center to the container's bounds: up to the top, then down into the container.
|
|
124
|
+
CGPoint containerAnchor = ANNAnchorInBounds(container.layer);
|
|
125
|
+
CATransform3D toContainer =
|
|
126
|
+
CATransform3DConcat(CATransform3DInvert(ANNTransformToTop(container.layer)),
|
|
127
|
+
CATransform3DMakeTranslation(containerAnchor.x, containerAnchor.y, 0));
|
|
128
|
+
CATransform3D whole = CATransform3DConcat(ANNTransformToTop(layer), toContainer);
|
|
129
|
+
// The center is where the view's center lands; the rest of the transform turns about it.
|
|
130
|
+
end.center = CGPointMake(whole.m41 / whole.m44, whole.m42 / whole.m44);
|
|
131
|
+
end.transform = CATransform3DConcat(
|
|
132
|
+
whole, CATransform3DMakeTranslation(-end.center.x, -end.center.y, 0));
|
|
80
133
|
end.cornerRadius = ANNCornerRadiusOf(view);
|
|
81
134
|
// The visible part: the element's bounds cut by every parent that clips (`overflow: hidden`, a scroll view) up to
|
|
82
135
|
// the screen's root, in the element's own coordinates, moved to the copy's (its bounds start at 0, 0).
|
|
@@ -103,6 +156,47 @@ static ANNFlightEnd ANNFlightEndOf(UIView *view, UIView *screenRoot, UIView *con
|
|
|
103
156
|
return end;
|
|
104
157
|
}
|
|
105
158
|
|
|
159
|
+
static BOOL ANNIsFiniteRect(CGRect rect) {
|
|
160
|
+
return isfinite(rect.origin.x) && isfinite(rect.origin.y) && isfinite(rect.size.width) &&
|
|
161
|
+
isfinite(rect.size.height);
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
static BOOL ANNFlightEndIsFinite(ANNFlightEnd end) {
|
|
165
|
+
const CATransform3D t = end.transform;
|
|
166
|
+
const CGFloat values[] = {t.m11, t.m12, t.m13, t.m14, t.m21, t.m22, t.m23, t.m24,
|
|
167
|
+
t.m31, t.m32, t.m33, t.m34, t.m41, t.m42, t.m43, t.m44};
|
|
168
|
+
for (CGFloat value : values) {
|
|
169
|
+
if (!isfinite(value)) {
|
|
170
|
+
return NO;
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
return isfinite(end.center.x) && isfinite(end.center.y) && isfinite(end.size.width) &&
|
|
174
|
+
isfinite(end.size.height) && isfinite(end.cornerRadius) && isfinite(end.visibleRadius) &&
|
|
175
|
+
ANNIsFiniteRect(end.visible);
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
// The parts of the end's transform, its scale moved into the size, the corners and the visible part (a mirror keeps
|
|
179
|
+
// its sign); NO when the transform flattens the view.
|
|
180
|
+
static BOOL ANNSplitFlightEnd(ANNFlightEnd *end) {
|
|
181
|
+
ANNTransformParts parts;
|
|
182
|
+
if (!ANNTransformPartsOf(end->transform, &parts)) {
|
|
183
|
+
return NO;
|
|
184
|
+
}
|
|
185
|
+
CGFloat scaleX = (CGFloat)std::fabs(parts.scale[0]);
|
|
186
|
+
CGFloat scaleY = (CGFloat)std::fabs(parts.scale[1]);
|
|
187
|
+
CGFloat scale = MIN(scaleX, scaleY);
|
|
188
|
+
parts.scale[0] = std::copysign(1.0, parts.scale[0]);
|
|
189
|
+
parts.scale[1] = std::copysign(1.0, parts.scale[1]);
|
|
190
|
+
end->parts = parts;
|
|
191
|
+
end->size = CGSizeMake(end->size.width * scaleX, end->size.height * scaleY);
|
|
192
|
+
end->cornerRadius *= scale;
|
|
193
|
+
end->visibleRadius *= scale;
|
|
194
|
+
end->visible = CGRectMake(end->visible.origin.x * scaleX, end->visible.origin.y * scaleY,
|
|
195
|
+
end->visible.size.width * scaleX,
|
|
196
|
+
end->visible.size.height * scaleY);
|
|
197
|
+
return YES;
|
|
198
|
+
}
|
|
199
|
+
|
|
106
200
|
// The picture of the view's layer and its sublayers at the screen's scale, in the layer's own coordinates.
|
|
107
201
|
static UIImage *ANNPictureOf(UIView *view) {
|
|
108
202
|
CGSize size = view.bounds.size;
|
|
@@ -121,6 +215,30 @@ static UIImage *ANNPictureOf(UIView *view) {
|
|
|
121
215
|
}];
|
|
122
216
|
}
|
|
123
217
|
|
|
218
|
+
// A layer at `frame` in its superlayer: its bounds and its position (its anchor is its center).
|
|
219
|
+
static void ANNPlaceLayer(CALayer *layer, CGRect frame) {
|
|
220
|
+
layer.bounds = CGRectMake(0, 0, frame.size.width, frame.size.height);
|
|
221
|
+
layer.position = CGPointMake(CGRectGetMidX(frame), CGRectGetMidY(frame));
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
// The core's animation of `keyPath` on `layer` (`ANNKeyframes`), under its key.
|
|
225
|
+
static void ANNAddKeyframes(CALayer *layer, NSString *keyPath, NSArray *values,
|
|
226
|
+
NSArray<NSNumber *> *times, NSTimeInterval length) {
|
|
227
|
+
CAKeyframeAnimation *animation = ANNKeyframes(keyPath, values, times, length);
|
|
228
|
+
if (animation) {
|
|
229
|
+
[layer addAnimation:animation forKey:ANNAnimationKey(keyPath)];
|
|
230
|
+
}
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
// The bounds and the position of a layer at `frame`, as values of its animations.
|
|
234
|
+
static NSValue *ANNBoundsValue(CGRect frame) {
|
|
235
|
+
return [NSValue valueWithCGRect:CGRectMake(0, 0, frame.size.width, frame.size.height)];
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
static NSValue *ANNPositionValue(CGRect frame) {
|
|
239
|
+
return [NSValue valueWithCGPoint:CGPointMake(CGRectGetMidX(frame), CGRectGetMidY(frame))];
|
|
240
|
+
}
|
|
241
|
+
|
|
124
242
|
@implementation ANNSharedElementFlight {
|
|
125
243
|
__weak UIView *_fromView;
|
|
126
244
|
__weak UIView *_toView;
|
|
@@ -129,7 +247,9 @@ static UIImage *ANNPictureOf(UIView *view) {
|
|
|
129
247
|
UIView *_copy;
|
|
130
248
|
UIImageView *_fromPicture;
|
|
131
249
|
UIImageView *_toPicture;
|
|
132
|
-
|
|
250
|
+
// The visible part of the copy: a plain layer with corners, as Core Animation can't animate a path whose corners
|
|
251
|
+
// change.
|
|
252
|
+
CALayer *_mask;
|
|
133
253
|
ANNFlightEnd _from;
|
|
134
254
|
ANNFlightEnd _to;
|
|
135
255
|
ANNTrack *_track;
|
|
@@ -140,15 +260,10 @@ static UIImage *ANNPictureOf(UIView *view) {
|
|
|
140
260
|
BOOL _restored;
|
|
141
261
|
}
|
|
142
262
|
|
|
143
|
-
+ (NSString *)textOf:(Text *)value {
|
|
144
|
-
NSString *text = [value withDefault:nil];
|
|
145
|
-
return [text isKindOfClass:NSString.class] && text.length > 0 ? text : nil;
|
|
146
|
-
}
|
|
147
|
-
|
|
148
263
|
+ (BOOL)allTargetsFound:(NSArray<ANNSharedElementTransitionOptions *> *)pairs
|
|
149
|
-
|
|
264
|
+
views:(ANNTransitionViews *)views {
|
|
150
265
|
for (ANNSharedElementTransitionOptions *pair in pairs) {
|
|
151
|
-
if (![
|
|
266
|
+
if (![views arrivingViewWithNativeID:ANNNativeIDOf(pair.toId)]) {
|
|
152
267
|
return NO;
|
|
153
268
|
}
|
|
154
269
|
}
|
|
@@ -156,27 +271,31 @@ static UIImage *ANNPictureOf(UIView *view) {
|
|
|
156
271
|
}
|
|
157
272
|
|
|
158
273
|
+ (NSArray<ANNSharedElementFlight *> *)
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
container:(UIView *)container {
|
|
274
|
+
flightsOf:(NSArray<ANNSharedElementTransitionOptions *> *)pairs
|
|
275
|
+
views:(ANNTransitionViews *)views
|
|
276
|
+
container:(UIView *)container {
|
|
163
277
|
NSMutableArray<ANNSharedElementFlight *> *flights = [NSMutableArray new];
|
|
164
278
|
NSHashTable<UIView *> *taken = [NSHashTable weakObjectsHashTable];
|
|
165
279
|
for (ANNSharedElementTransitionOptions *pair in pairs) {
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
UIView *
|
|
169
|
-
|
|
280
|
+
NSString *fromId = ANNNativeIDOf(pair.fromId);
|
|
281
|
+
NSString *toId = ANNNativeIDOf(pair.toId);
|
|
282
|
+
UIView *from = [views leavingViewWithNativeID:fromId];
|
|
283
|
+
UIView *to = [views arrivingViewWithNativeID:toId];
|
|
170
284
|
if (!from || !to || from == to || [taken containsObject:from] ||
|
|
171
285
|
[taken containsObject:to]) {
|
|
172
286
|
continue;
|
|
173
287
|
}
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
288
|
+
NSString *name = [NSString stringWithFormat:@"'%@' -> '%@'", fromId, toId];
|
|
289
|
+
__block ANNSharedElementFlight *flight = nil;
|
|
290
|
+
ANNElementStep(name, ^{
|
|
291
|
+
flight = [[self alloc] initWithPair:pair
|
|
292
|
+
from:from
|
|
293
|
+
to:to
|
|
294
|
+
leavingRoot:views.leavingRoot
|
|
295
|
+
arrivingRoot:views.arrivingRoot
|
|
296
|
+
container:container
|
|
297
|
+
name:name];
|
|
298
|
+
});
|
|
180
299
|
if (flight) {
|
|
181
300
|
[taken addObject:from];
|
|
182
301
|
[taken addObject:to];
|
|
@@ -193,10 +312,18 @@ static UIImage *ANNPictureOf(UIView *view) {
|
|
|
193
312
|
}
|
|
194
313
|
return a->_zIndex < b->_zIndex ? NSOrderedAscending : NSOrderedDescending;
|
|
195
314
|
}];
|
|
315
|
+
// A copy that can't take off goes away, and its pair's views show as they were.
|
|
316
|
+
NSMutableArray<ANNSharedElementFlight *> *flying = [NSMutableArray new];
|
|
196
317
|
for (ANNSharedElementFlight *flight in ordered) {
|
|
197
|
-
|
|
318
|
+
if (ANNElementStep(flight.name, ^{
|
|
319
|
+
[flight takeOffIn:container];
|
|
320
|
+
})) {
|
|
321
|
+
[flying addObject:flight];
|
|
322
|
+
} else {
|
|
323
|
+
[flight restore];
|
|
324
|
+
}
|
|
198
325
|
}
|
|
199
|
-
return
|
|
326
|
+
return flying;
|
|
200
327
|
}
|
|
201
328
|
|
|
202
329
|
- (instancetype)initWithPair:(ANNSharedElementTransitionOptions *)pair
|
|
@@ -204,19 +331,32 @@ static UIImage *ANNPictureOf(UIView *view) {
|
|
|
204
331
|
to:(UIView *)to
|
|
205
332
|
leavingRoot:(UIView *)leavingRoot
|
|
206
333
|
arrivingRoot:(UIView *)arrivingRoot
|
|
207
|
-
container:(UIView *)container
|
|
334
|
+
container:(UIView *)container
|
|
335
|
+
name:(NSString *)name {
|
|
208
336
|
// A view of no size gives no picture: the pair is skipped and both views stay as they are.
|
|
209
337
|
if (from.bounds.size.width <= 0 || from.bounds.size.height <= 0 || to.bounds.size.width <= 0 ||
|
|
210
338
|
to.bounds.size.height <= 0) {
|
|
339
|
+
ANNElementSkipped(name, @"a view of the pair has no size, it isn't laid out");
|
|
211
340
|
return nil;
|
|
212
341
|
}
|
|
213
342
|
if (!(self = [super init])) {
|
|
214
343
|
return nil;
|
|
215
344
|
}
|
|
345
|
+
_name = [name copy];
|
|
216
346
|
_fromView = from;
|
|
217
347
|
_toView = to;
|
|
218
348
|
_from = ANNFlightEndOf(from, leavingRoot, container);
|
|
219
349
|
_to = ANNFlightEndOf(to, arrivingRoot, container);
|
|
350
|
+
// A place that isn't a number would stop the copy's layer with an exception at its first frame.
|
|
351
|
+
if (!ANNFlightEndIsFinite(_from) || !ANNFlightEndIsFinite(_to)) {
|
|
352
|
+
ANNElementSkipped(name, @"the place of a view of the pair can't be worked out");
|
|
353
|
+
return nil;
|
|
354
|
+
}
|
|
355
|
+
// A transform that flattens the view (a scale of 0) has no parts to fly between.
|
|
356
|
+
if (!ANNSplitFlightEnd(&_from) || !ANNSplitFlightEnd(&_to)) {
|
|
357
|
+
ANNElementSkipped(name, @"the transform of a view of the pair flattens it");
|
|
358
|
+
return nil;
|
|
359
|
+
}
|
|
220
360
|
_text = ANNIsText(from) || ANNIsText(to);
|
|
221
361
|
_grows = _to.size.height >= _from.size.height;
|
|
222
362
|
_rightToLeft =
|
|
@@ -231,6 +371,7 @@ static UIImage *ANNPictureOf(UIView *view) {
|
|
|
231
371
|
UIImage *fromImage = ANNPictureOf(from);
|
|
232
372
|
UIImage *toImage = ANNPictureOf(to);
|
|
233
373
|
if (!fromImage || !toImage) {
|
|
374
|
+
ANNElementSkipped(name, @"no picture of a view of the pair can be taken");
|
|
234
375
|
return nil;
|
|
235
376
|
}
|
|
236
377
|
_copy = [UIView new];
|
|
@@ -243,7 +384,8 @@ static UIImage *ANNPictureOf(UIView *view) {
|
|
|
243
384
|
// A text's pictures are neither clipped nor masked.
|
|
244
385
|
_copy.clipsToBounds = !_text;
|
|
245
386
|
if (!_text && (_from.clipped || _to.clipped)) {
|
|
246
|
-
_mask = [
|
|
387
|
+
_mask = [CALayer layer];
|
|
388
|
+
_mask.backgroundColor = UIColor.blackColor.CGColor;
|
|
247
389
|
_copy.layer.mask = _mask;
|
|
248
390
|
}
|
|
249
391
|
[_copy addSubview:_fromPicture];
|
|
@@ -260,71 +402,168 @@ static UIImage *ANNPictureOf(UIView *view) {
|
|
|
260
402
|
[container addSubview:_copy];
|
|
261
403
|
from.hidden = YES;
|
|
262
404
|
to.hidden = YES;
|
|
263
|
-
[self
|
|
405
|
+
[self placeAtTime:0];
|
|
264
406
|
}
|
|
265
407
|
|
|
266
408
|
- (UIView *)copyView {
|
|
267
409
|
return _copy;
|
|
268
410
|
}
|
|
269
411
|
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
return _track.endTime;
|
|
274
|
-
}
|
|
275
|
-
|
|
276
|
-
- (void)applyAtTime:(NSTimeInterval)time {
|
|
277
|
-
if (_restored) {
|
|
278
|
-
return;
|
|
279
|
-
}
|
|
412
|
+
// The copy's whole state at `time`: its own geometry, its pictures' and its visible part's.
|
|
413
|
+
- (ANNFlightState)stateAtTime:(NSTimeInterval)time {
|
|
414
|
+
ANNFlightState state;
|
|
280
415
|
double f = [_track fractionAt:time];
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
416
|
+
state.size = ANNInterpolateSize(_from.size, _to.size, f);
|
|
417
|
+
state.center = ANNInterpolatePoint(_from.center, _to.center, f);
|
|
418
|
+
state.transform = ANNTransformOfParts(ANNInterpolateTransformParts(_from.parts, _to.parts, f));
|
|
419
|
+
state.cornerRadius = 0;
|
|
420
|
+
state.mask = CGRectZero;
|
|
421
|
+
state.maskRadius = 0;
|
|
286
422
|
if (_text) {
|
|
287
|
-
[self
|
|
288
|
-
return;
|
|
423
|
+
[self placeTextPicturesOf:&state atTime:time];
|
|
424
|
+
return state;
|
|
289
425
|
}
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
426
|
+
state.cornerRadius = ANNInterpolateNumber(_from.cornerRadius, _to.cornerRadius, f);
|
|
427
|
+
CGRect whole = CGRectMake(0, 0, state.size.width, state.size.height);
|
|
428
|
+
state.fromFrame = whole;
|
|
429
|
+
state.toFrame = whole;
|
|
430
|
+
state.fromAlpha = 1;
|
|
431
|
+
state.toAlpha = (CGFloat)f;
|
|
295
432
|
if (_mask) {
|
|
296
433
|
CGRect fromWhole = CGRectMake(0, 0, _from.size.width, _from.size.height);
|
|
297
434
|
CGRect toWhole = CGRectMake(0, 0, _to.size.width, _to.size.height);
|
|
298
435
|
CGRect fromVisible = _from.clipped ? _from.visible : fromWhole;
|
|
299
436
|
CGRect toVisible = _to.clipped ? _to.visible : toWhole;
|
|
300
|
-
|
|
437
|
+
state.mask = ANNInterpolateRect(fromVisible, toVisible, f);
|
|
438
|
+
// At most half the shorter side, as a rounded path has it.
|
|
301
439
|
CGFloat radius = ANNInterpolateNumber(_from.visibleRadius, _to.visibleRadius, f);
|
|
302
|
-
|
|
303
|
-
|
|
440
|
+
CGFloat half = MIN(state.mask.size.width, state.mask.size.height) / 2;
|
|
441
|
+
state.maskRadius = MAX(MIN(radius, half), 0);
|
|
304
442
|
}
|
|
443
|
+
return state;
|
|
305
444
|
}
|
|
306
445
|
|
|
307
446
|
// The text's pictures keep their aspect at the height of the copy, at the line's start; they swap by the clock,
|
|
308
447
|
// linearly, in the first quarter of the flight when the text grows, in the last when it shrinks.
|
|
309
|
-
- (void)
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
448
|
+
- (void)placeTextPicturesOf:(ANNFlightState *)state atTime:(NSTimeInterval)time {
|
|
449
|
+
CGRect frames[2];
|
|
450
|
+
UIImageView *pictures[2] = {_fromPicture, _toPicture};
|
|
451
|
+
for (int index = 0; index < 2; index++) {
|
|
452
|
+
CGSize imageSize = pictures[index].image.size;
|
|
453
|
+
CGFloat height = state->size.height;
|
|
313
454
|
CGFloat width = imageSize.height > 0 ? imageSize.width * height / imageSize.height : 0;
|
|
314
|
-
CGFloat x = _rightToLeft ? size.width - width : 0;
|
|
315
|
-
|
|
455
|
+
CGFloat x = _rightToLeft ? state->size.width - width : 0;
|
|
456
|
+
frames[index] = CGRectMake(x, 0, width, height);
|
|
316
457
|
}
|
|
458
|
+
state->fromFrame = frames[0];
|
|
459
|
+
state->toFrame = frames[1];
|
|
460
|
+
double swap = [self swapAtTime:time];
|
|
461
|
+
state->fromAlpha = (CGFloat)(1 - swap);
|
|
462
|
+
state->toAlpha = (CGFloat)swap;
|
|
463
|
+
}
|
|
464
|
+
|
|
465
|
+
// The quarter of the flight the text's pictures swap in.
|
|
466
|
+
- (NSTimeInterval)swapStart {
|
|
317
467
|
NSTimeInterval duration = _track.duration;
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
468
|
+
return _track.delay + (_grows ? 0 : duration - duration / 4);
|
|
469
|
+
}
|
|
470
|
+
|
|
471
|
+
- (double)swapAtTime:(NSTimeInterval)time {
|
|
472
|
+
NSTimeInterval quarter = _track.duration / 4;
|
|
321
473
|
if (quarter <= 0) {
|
|
322
|
-
|
|
323
|
-
}
|
|
324
|
-
|
|
474
|
+
return time >= _track.delay ? 1 : 0;
|
|
475
|
+
}
|
|
476
|
+
return MIN(MAX((time - [self swapStart]) / quarter, 0.0), 1.0);
|
|
477
|
+
}
|
|
478
|
+
|
|
479
|
+
// The copy shows its state at `time` (its own values, with no animation).
|
|
480
|
+
- (void)placeAtTime:(NSTimeInterval)time {
|
|
481
|
+
ANNFlightState state = [self stateAtTime:time];
|
|
482
|
+
[CATransaction begin];
|
|
483
|
+
[CATransaction setDisableActions:YES];
|
|
484
|
+
_copy.layer.transform = CATransform3DIdentity;
|
|
485
|
+
_copy.bounds = CGRectMake(0, 0, state.size.width, state.size.height);
|
|
486
|
+
_copy.center = state.center;
|
|
487
|
+
_copy.layer.transform = state.transform;
|
|
488
|
+
if (!_text) {
|
|
489
|
+
_copy.layer.cornerRadius = state.cornerRadius;
|
|
490
|
+
}
|
|
491
|
+
ANNPlaceLayer(_fromPicture.layer, state.fromFrame);
|
|
492
|
+
ANNPlaceLayer(_toPicture.layer, state.toFrame);
|
|
493
|
+
_fromPicture.alpha = state.fromAlpha;
|
|
494
|
+
_toPicture.alpha = state.toAlpha;
|
|
495
|
+
if (_mask) {
|
|
496
|
+
ANNPlaceLayer(_mask, state.mask);
|
|
497
|
+
_mask.cornerRadius = state.maskRadius;
|
|
498
|
+
}
|
|
499
|
+
[CATransaction commit];
|
|
500
|
+
}
|
|
501
|
+
|
|
502
|
+
#pragma mark - ANNFrameClient
|
|
503
|
+
|
|
504
|
+
- (NSTimeInterval)endTime {
|
|
505
|
+
return _track.endTime;
|
|
506
|
+
}
|
|
507
|
+
|
|
508
|
+
- (void)addAnimationsWithLength:(NSTimeInterval)length {
|
|
509
|
+
if (_restored) {
|
|
510
|
+
return;
|
|
511
|
+
}
|
|
512
|
+
NSMutableArray<NSNumber *> *marks =
|
|
513
|
+
[NSMutableArray arrayWithObjects:@(_track.delay), @(_track.endTime), nil];
|
|
514
|
+
if (_text) {
|
|
515
|
+
[marks addObject:@([self swapStart])];
|
|
516
|
+
[marks addObject:@([self swapStart] + _track.duration / 4)];
|
|
517
|
+
}
|
|
518
|
+
NSArray<NSNumber *> *times = ANNSampleTimes(_track.endTime, length, marks);
|
|
519
|
+
NSMutableArray *bounds = [NSMutableArray new];
|
|
520
|
+
NSMutableArray *positions = [NSMutableArray new];
|
|
521
|
+
NSMutableArray *transforms = [NSMutableArray new];
|
|
522
|
+
NSMutableArray *radii = [NSMutableArray new];
|
|
523
|
+
NSMutableArray *fromBounds = [NSMutableArray new];
|
|
524
|
+
NSMutableArray *fromPositions = [NSMutableArray new];
|
|
525
|
+
NSMutableArray *fromAlphas = [NSMutableArray new];
|
|
526
|
+
NSMutableArray *toBounds = [NSMutableArray new];
|
|
527
|
+
NSMutableArray *toPositions = [NSMutableArray new];
|
|
528
|
+
NSMutableArray *toAlphas = [NSMutableArray new];
|
|
529
|
+
NSMutableArray *maskBounds = [NSMutableArray new];
|
|
530
|
+
NSMutableArray *maskPositions = [NSMutableArray new];
|
|
531
|
+
NSMutableArray *maskRadii = [NSMutableArray new];
|
|
532
|
+
for (NSNumber *time in times) {
|
|
533
|
+
ANNFlightState state = [self stateAtTime:time.doubleValue];
|
|
534
|
+
CGRect whole = CGRectMake(0, 0, state.size.width, state.size.height);
|
|
535
|
+
[bounds addObject:ANNBoundsValue(whole)];
|
|
536
|
+
[positions addObject:[NSValue valueWithCGPoint:state.center]];
|
|
537
|
+
[transforms addObject:[NSValue valueWithCATransform3D:state.transform]];
|
|
538
|
+
[radii addObject:@(state.cornerRadius)];
|
|
539
|
+
[fromBounds addObject:ANNBoundsValue(state.fromFrame)];
|
|
540
|
+
[fromPositions addObject:ANNPositionValue(state.fromFrame)];
|
|
541
|
+
[fromAlphas addObject:@(state.fromAlpha)];
|
|
542
|
+
[toBounds addObject:ANNBoundsValue(state.toFrame)];
|
|
543
|
+
[toPositions addObject:ANNPositionValue(state.toFrame)];
|
|
544
|
+
[toAlphas addObject:@(state.toAlpha)];
|
|
545
|
+
[maskBounds addObject:ANNBoundsValue(state.mask)];
|
|
546
|
+
[maskPositions addObject:ANNPositionValue(state.mask)];
|
|
547
|
+
[maskRadii addObject:@(state.maskRadius)];
|
|
548
|
+
}
|
|
549
|
+
CALayer *copy = _copy.layer;
|
|
550
|
+
ANNAddKeyframes(copy, @"bounds", bounds, times, length);
|
|
551
|
+
ANNAddKeyframes(copy, @"position", positions, times, length);
|
|
552
|
+
ANNAddKeyframes(copy, @"transform", transforms, times, length);
|
|
553
|
+
if (!_text) {
|
|
554
|
+
ANNAddKeyframes(copy, @"cornerRadius", radii, times, length);
|
|
555
|
+
}
|
|
556
|
+
ANNAddKeyframes(_fromPicture.layer, @"bounds", fromBounds, times, length);
|
|
557
|
+
ANNAddKeyframes(_fromPicture.layer, @"position", fromPositions, times, length);
|
|
558
|
+
ANNAddKeyframes(_fromPicture.layer, @"opacity", fromAlphas, times, length);
|
|
559
|
+
ANNAddKeyframes(_toPicture.layer, @"bounds", toBounds, times, length);
|
|
560
|
+
ANNAddKeyframes(_toPicture.layer, @"position", toPositions, times, length);
|
|
561
|
+
ANNAddKeyframes(_toPicture.layer, @"opacity", toAlphas, times, length);
|
|
562
|
+
if (_mask) {
|
|
563
|
+
ANNAddKeyframes(_mask, @"bounds", maskBounds, times, length);
|
|
564
|
+
ANNAddKeyframes(_mask, @"position", maskPositions, times, length);
|
|
565
|
+
ANNAddKeyframes(_mask, @"cornerRadius", maskRadii, times, length);
|
|
325
566
|
}
|
|
326
|
-
_fromPicture.alpha = (CGFloat)(1 - swap);
|
|
327
|
-
_toPicture.alpha = (CGFloat)swap;
|
|
328
567
|
}
|
|
329
568
|
|
|
330
569
|
- (void)restore {
|
|
@@ -5,7 +5,8 @@ NS_ASSUME_NONNULL_BEGIN
|
|
|
5
5
|
|
|
6
6
|
// The interpolation of values: from + f·(to − from) per component, where f is the share of the way a track gives
|
|
7
7
|
// (`ANNTrack fractionAt:`); exactly `from` at f = 0 and exactly `to` at f = 1, whatever the floating point would give.
|
|
8
|
-
// iOS never interpolates colors: a shared element flies as pictures.
|
|
8
|
+
// iOS never interpolates colors: a shared element flies as pictures. A transform goes by its parts
|
|
9
|
+
// (`ANNTransformParts`).
|
|
9
10
|
|
|
10
11
|
/// A number.
|
|
11
12
|
static inline CGFloat ANNInterpolateNumber(CGFloat from, CGFloat to, double f) {
|
|
@@ -37,33 +38,4 @@ static inline CGRect ANNInterpolateRect(CGRect from, CGRect to, double f) {
|
|
|
37
38
|
return CGRectMake(origin.x, origin.y, size.width, size.height);
|
|
38
39
|
}
|
|
39
40
|
|
|
40
|
-
/// A 4×4 transform, element by element (a shared element with a `transform` style, as iOS does it now).
|
|
41
|
-
static inline CATransform3D ANNInterpolateTransform(CATransform3D from, CATransform3D to,
|
|
42
|
-
double f) {
|
|
43
|
-
if (f == 0) {
|
|
44
|
-
return from;
|
|
45
|
-
}
|
|
46
|
-
if (f == 1) {
|
|
47
|
-
return to;
|
|
48
|
-
}
|
|
49
|
-
CATransform3D t;
|
|
50
|
-
t.m11 = ANNInterpolateNumber(from.m11, to.m11, f);
|
|
51
|
-
t.m12 = ANNInterpolateNumber(from.m12, to.m12, f);
|
|
52
|
-
t.m13 = ANNInterpolateNumber(from.m13, to.m13, f);
|
|
53
|
-
t.m14 = ANNInterpolateNumber(from.m14, to.m14, f);
|
|
54
|
-
t.m21 = ANNInterpolateNumber(from.m21, to.m21, f);
|
|
55
|
-
t.m22 = ANNInterpolateNumber(from.m22, to.m22, f);
|
|
56
|
-
t.m23 = ANNInterpolateNumber(from.m23, to.m23, f);
|
|
57
|
-
t.m24 = ANNInterpolateNumber(from.m24, to.m24, f);
|
|
58
|
-
t.m31 = ANNInterpolateNumber(from.m31, to.m31, f);
|
|
59
|
-
t.m32 = ANNInterpolateNumber(from.m32, to.m32, f);
|
|
60
|
-
t.m33 = ANNInterpolateNumber(from.m33, to.m33, f);
|
|
61
|
-
t.m34 = ANNInterpolateNumber(from.m34, to.m34, f);
|
|
62
|
-
t.m41 = ANNInterpolateNumber(from.m41, to.m41, f);
|
|
63
|
-
t.m42 = ANNInterpolateNumber(from.m42, to.m42, f);
|
|
64
|
-
t.m43 = ANNInterpolateNumber(from.m43, to.m43, f);
|
|
65
|
-
t.m44 = ANNInterpolateNumber(from.m44, to.m44, f);
|
|
66
|
-
return t;
|
|
67
|
-
}
|
|
68
|
-
|
|
69
41
|
NS_ASSUME_NONNULL_END
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
#import <QuartzCore/QuartzCore.h>
|
|
2
|
+
#import <UIKit/UIKit.h>
|
|
3
|
+
|
|
4
|
+
NS_ASSUME_NONNULL_BEGIN
|
|
5
|
+
|
|
6
|
+
/// A 4×4 transform split into the parts it is made of (the decomposition of CSS Transforms Level 2): applied to a point
|
|
7
|
+
/// in the order scale, skew, rotation, translation, perspective. Two transforms interpolate part by part, the rotation
|
|
8
|
+
/// along the shorter arc between the two (a quaternion's slerp), so a rotation never collapses on the way.
|
|
9
|
+
typedef struct {
|
|
10
|
+
double translate[3];
|
|
11
|
+
double scale[3];
|
|
12
|
+
/// The shears xy, xz, yz.
|
|
13
|
+
double skew[3];
|
|
14
|
+
double perspective[4];
|
|
15
|
+
/// x, y, z, w.
|
|
16
|
+
double quaternion[4];
|
|
17
|
+
} ANNTransformParts;
|
|
18
|
+
|
|
19
|
+
/// The parts of no transform.
|
|
20
|
+
FOUNDATION_EXPORT ANNTransformParts ANNTransformPartsIdentity(void);
|
|
21
|
+
|
|
22
|
+
/// The parts of `transform` into `parts`; NO when it can't be split (a scale of 0 flattens it).
|
|
23
|
+
FOUNDATION_EXPORT BOOL ANNTransformPartsOf(CATransform3D transform, ANNTransformParts *parts);
|
|
24
|
+
|
|
25
|
+
/// The transform the parts make.
|
|
26
|
+
FOUNDATION_EXPORT CATransform3D ANNTransformOfParts(ANNTransformParts parts);
|
|
27
|
+
|
|
28
|
+
/// The parts at `f` of the way: each number from + f·(to − from), the rotation by slerp along the shorter arc; exactly
|
|
29
|
+
/// `from` at f = 0 and `to` at f = 1. Two rotations half a turn apart go either way.
|
|
30
|
+
FOUNDATION_EXPORT ANNTransformParts ANNInterpolateTransformParts(ANNTransformParts from,
|
|
31
|
+
ANNTransformParts to, double f);
|
|
32
|
+
|
|
33
|
+
/// The rotation of the parts as the turns about x, then y, then z (degrees, each in −180…180), the order a view's
|
|
34
|
+
/// tracks compose them in (`ANNViewTracks`).
|
|
35
|
+
FOUNDATION_EXPORT void ANNRotationDegreesOf(ANNTransformParts parts, double *x, double *y,
|
|
36
|
+
double *z);
|
|
37
|
+
|
|
38
|
+
/// The shears of the parts as a transform of their own (the scale, rotation and the rest aside).
|
|
39
|
+
FOUNDATION_EXPORT CATransform3D ANNSkewTransformOf(ANNTransformParts parts);
|
|
40
|
+
|
|
41
|
+
#if DEBUG
|
|
42
|
+
/// Development only (there is no iOS test target): splits and rebuilds known transforms and checks the rotations a
|
|
43
|
+
/// shared element takes (0° → 90°, 0° → 180°, 45° → −45°, 270°, 170° → −170°, a scale, a tilt), once; a mismatch is
|
|
44
|
+
/// logged.
|
|
45
|
+
FOUNDATION_EXPORT void ANNTransformPartsSelfCheck(void);
|
|
46
|
+
#endif
|
|
47
|
+
|
|
48
|
+
NS_ASSUME_NONNULL_END
|