One Logo Pool Ball
wwwwwwwwwwwwwwwwwww

Zoom Transitions

Native iOS 18+ zoom transitions between screens

Native iOS 18+ zoom transitions. The destination screen expands from a source element with a fluid animation.

Requires iOS 18+. Falls back to standard push transition on older versions.
import { One, Stack, useParams, useRouter } from 'one'
import { Pressable, Text, View } from 'react-native'
// source screen: wrap the tappable element
function 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 anywhere
function 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>
)
}

Tips

Props

ZoomTransitionSource 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.

PropsTypeDescription
identifierstringRequired source identifier matched by the destination enabler.
stringRequired source identifier matched by the destination enabler.
alignmentSourceAlignmentRectOptional source alignment rectangle.
SourceAlignmentRectOptional source alignment rectangle.
animateAspectRatioChangebooleanAdjust the destination rectangle to the source aspect ratio.
booleanAdjust the destination rectangle to the source aspect ratio.
PropsTypeDescription
zoomTransitionSourceIdentifierstringRequired identifier of the mounted source element.
stringRequired identifier of the mounted source element.
dismissalBoundsRectDismissalBoundsRect | nullOptional bounds for beginning an interactive dismissal.
DismissalBoundsRect | nullOptional bounds for beginning an interactive dismissal.
PropsTypeDescription
identifierstringRequired identifier matched by the source and destination enabler.
stringRequired identifier matched by the source and destination enabler.
PropsTypeDescription
xnumberHorizontal source origin in points.
numberHorizontal source origin in points.
ynumberVertical source origin in points.
numberVertical source origin in points.
widthnumberSource rectangle width in points.
numberSource rectangle width in points.
heightnumberSource rectangle height in points.
numberSource rectangle height in points.
PropsTypeDescription
minXnumberOptional minimum horizontal gesture location.
numberOptional minimum horizontal gesture location.
maxXnumberOptional maximum horizontal gesture location.
numberOptional maximum horizontal gesture location.
minYnumberOptional minimum vertical gesture location.
numberOptional minimum vertical gesture location.
maxYnumberOptional maximum vertical gesture location.
numberOptional maximum vertical gesture location.

Edit this page on GitHub.