Shared Element Transitions
Top Level
The core idea behind the shared element transition API is that any screen can define some number of views that are
SharedElementGroups and each SharedElementGroup can have some number of views that are SharedElements inside of it.
Each SharedElementGroup has an identifier (a string) which uniquely identifies it on the screen.
Each SharedElement has an identifier (a string) which uniquely identifies it inside of the SharedElementGroup
Also, SharedElements need not live inside of a SharedElementGroup, but then they can only be used in the to portion
of the transition, and not the from part.
If a transitionGroup is specified as an option in the navigation call (ie, Navigator.push), then a shared element
transition will be attempted with the provided id of the SharedElementGroup on the screen that you are navigating away
from.
Example
import React from 'react';
import { View, Image } from 'react-native';
import Navigator, { SharedElement, SharedElementGroup } from 'native-navigation';
const onPress = id => () =>
Navigator.push('ToScreen', { id }, {
transitionGroup: id,
});
class FromScreen extends React.Component {
render() {
const { posters } = this.props;
return (
<View>
{posters.map(poster => (
<SharedElementGroup id={poster.id}>
<Touchable onPress={onPress(poster.id)}>
<SharedElement
type="poster"
typeId={poster.id}
>
<Image source={{ uri: poster.url }} />
</SharedElement>
</Touchable>
</SharedElementGroup>
))}
</View>
);
}
}
import React from 'react';
import { View, Image } from 'react-native';
import Navigator, { SharedElement, SharedElementGroup } from 'native-navigation';
class ToScreen extends React.Component {
render() {
return (
<View>
{/* ... */}
<SharedElement
type="poster"
typeId={poster.id}
>
<Image source={{ uri: poster.url }} />
</SharedElement>
{/* ... */}
</View>
);
}
}
Shared Element Identifiers
This section has not yet been filled out
How it works (iOS)
The animation is executed by creating a number of snapshots (using snapshotViewAfterScreenUpdates ) and animating them inside of an animation container using a UIViewControllerTransitioningDelegate
The snapshot itself is several steps, as outlined below. Provided you have the following three inputs:
fromViewController: The view controller you are navigating away fromtoViewController: The view controller you are navigating totransitionGroup: the id of the transition group in thefromViewControllerthat is going to be involved in the transition.
With those parameters, we do the following:
- Snapshot
fromViewControllerand put the snapshot on top of the view hierarchy to cover the screen - In
fromViewControllercollect snapshots of everySharedElementinside of theSharedElementGroupwith id matchingtransitionGroup. - Snapshot the entire
fromViewControllerview hierarchy with eachSharedElementfrom #2 havingalphaset to 0. - In
toViewControllercollect snapshots of everySharedElement. - Snapshot the entire
toViewControllerview hierarchy with eachSharedElementfrom #4 havingalphaset to 0. - Find all of the matching
SharedElementsintoViewControllerandfromViewController, matching bytypeIdetc. - Remove snapshot from #1. Insert snapshots into the animation container in the following order:
- full screen snapshot of
fromViewControllerminus shared elements - all shared elements from
fromViewControllerwithout a match - full screen snapshot of
toViewControllerminus shared elements (set alpha to 0) - all shared elements from
toViewControllerwithout a match (set alpha to 0) - all shared elements from
fromViewControllerwith matches intoViewController
- full screen snapshot of
- Execute a
UIView.animateWithDuration(...)and set the following things in the animation:- full screen snapshot of
toViewControllerminus shared elements (set alpha to 1) - all shared elements from
toViewControllerwithout a match (set alpha to 1) - all shared elements from
fromViewControllerwith matches intoViewController:- set
.centerto the.centerof the corresponding matched element - set
.transformto be an XY scale transform that matches the ratio of the widths/heights of the element relative to its matched pair.
- set
- full screen snapshot of
- On completion of animation, remove the animation container completely.
How it works (Android)
This section has not yet been filled out
Common Issues
White screen on iPhone 7 Simulators:
Shared Element Transitions use custom transition coordinators and view snapshotting on iOS. There is a known issue with these on iPhone 7 Simulators. In these simulators, the whole screen will appear white and not work. This affects simulators only and not real devices.