Native iOS 18+ zoom transitions between screens
Native iOS 18+ zoom transitions. The destination screen expands from a source element with a fluid animation.
import { One, Stack, useParams, useRouter } from 'one'import { Pressable, Text, View } from 'react-native'
// source screen: wrap the tappable elementfunction ListScreen() { const router = useRouter() return ( <One.iOS.ZoomTransitionSource identifier="item-1"> <Pressable onPress={() => router.push('/detail?id=item-1')}> <Text>Mountain View</Text> </Pressable> </One.iOS.ZoomTransitionSource> )}
// destination screen: place the enabler anywherefunction DetailScreen() { const { id } = useParams() return ( <View> <Stack.Screen options={{ headerShown: false }} /> <One.iOS.ZoomTransitionEnabler zoomTransitionSourceIdentifier={id} /> <One.iOS.ZoomTransitionAlignmentRectDetector identifier={id}> <View collapsable={false}> <Text>Detail for {id}</Text> </View> </One.iOS.ZoomTransitionAlignmentRectDetector> </View> )}headerShown: false on the detail screen to avoid the header overlapping during the zoom animationidentifier must match between ZoomTransitionSource and ZoomTransitionEnablerOne.iOS.ZoomTransitionAlignmentRectDetector on the destination to align the zoom to a specific elementZoomTransitionSource takes a required identifier, an optional
alignment rect (x, y, width, height), and
animateAspectRatioChange. ZoomTransitionEnabler takes the required
zoomTransitionSourceIdentifier plus an optional dismissalBoundsRect
(minX, maxX, minY, maxY) that bounds the dismiss gesture.
ZoomTransitionAlignmentRectDetector takes the matching identifier and
wraps the destination element.
Keep the source element mounted while the destination is open. UIKit resolves
that element again when returning. The detector has one native child; use a
non-collapsible View when that child wraps other content. Its destination
rectangle is retained for the current transition’s dismissal after React removes
the detector.
| Props | Type | Description |
|---|---|---|
identifierstringRequired source identifier matched by the destination enabler. | string | Required source identifier matched by the destination enabler. |
alignmentSourceAlignmentRectOptional source alignment rectangle. | SourceAlignmentRect | Optional source alignment rectangle. |
animateAspectRatioChangebooleanAdjust the destination rectangle to the source aspect ratio. | boolean | Adjust the destination rectangle to the source aspect ratio. |
| Props | Type | Description |
|---|---|---|
zoomTransitionSourceIdentifierstringRequired identifier of the mounted source element. | string | Required identifier of the mounted source element. |
dismissalBoundsRectDismissalBoundsRect | nullOptional bounds for beginning an interactive dismissal. | DismissalBoundsRect | null | Optional bounds for beginning an interactive dismissal. |
| Props | Type | Description |
|---|---|---|
identifierstringRequired identifier matched by the source and destination enabler. | string | Required identifier matched by the source and destination enabler. |
| Props | Type | Description |
|---|---|---|
xnumberHorizontal source origin in points. | number | Horizontal source origin in points. |
ynumberVertical source origin in points. | number | Vertical source origin in points. |
widthnumberSource rectangle width in points. | number | Source rectangle width in points. |
heightnumberSource rectangle height in points. | number | Source rectangle height in points. |
| Props | Type | Description |
|---|---|---|
minXnumberOptional minimum horizontal gesture location. | number | Optional minimum horizontal gesture location. |
maxXnumberOptional maximum horizontal gesture location. | number | Optional maximum horizontal gesture location. |
minYnumberOptional minimum vertical gesture location. | number | Optional minimum vertical gesture location. |
maxYnumberOptional maximum vertical gesture location. | number | Optional maximum vertical gesture location. |
Edit this page on GitHub.