@@ -29,23 +29,75 @@ type Props<T extends Route> = {
2929 style ?: StyleProp < ViewStyle > ;
3030} ;
3131
32- const { interpolate, multiply } = Animated ;
32+ const { interpolate, add } = Animated ;
33+
34+ const UIKitPreset : HeaderAnimationPreset = {
35+ styleInterpolator : ( { current, next, layout } : InterpolationProps ) => {
36+ /**
37+ * NOTE: this offset calculation is an approximation that gives us
38+ * decent results in many cases, but it is ultimately a poor substitute
39+ * for text measurement. See the comment on title for more information.
40+ *
41+ * - 70 is the width of the left button area.
42+ * - 25 is the width of the left button icon (to account for label offset)
43+ */
44+ const buttonAreaSize = 70 ;
45+ const buttonIconSize = 25 ;
46+ const titleOffset = layout . width / 2 - buttonAreaSize + buttonIconSize ;
47+ const backTitleOffset = layout . width / 2 - buttonAreaSize - buttonIconSize ;
48+
49+ const progress = add ( current , next ? next : 0 ) ;
50+
51+ return {
52+ leftButtonStyle : {
53+ opacity : interpolate ( progress , {
54+ inputRange : [ 0 , 1 , 2 ] ,
55+ outputRange : [ 0 , 1 , 0 ] ,
56+ } ) ,
57+ } ,
58+ backTitleStyle : {
59+ opacity : interpolate ( progress , {
60+ inputRange : [ 0.7 , 1 , 1.3 ] ,
61+ outputRange : [ 0 , 1 , 0 ] ,
62+ } ) ,
63+ transform : [
64+ {
65+ translateX : interpolate ( progress , {
66+ inputRange : [ 0 , 1 , 2 ] ,
67+ outputRange : [ backTitleOffset , 0 , - backTitleOffset ] ,
68+ } ) ,
69+ } ,
70+ ] ,
71+ } ,
72+ titleStyle : {
73+ opacity : interpolate ( progress , {
74+ inputRange : [ 0.5 , 1 , 1.7 ] ,
75+ outputRange : [ 0 , 1 , 0 ] ,
76+ } ) ,
77+ transform : [
78+ {
79+ translateX : interpolate ( progress , {
80+ inputRange : [ 0 , 1 , 2 ] ,
81+ outputRange : [ titleOffset , 0 , - titleOffset ] ,
82+ } ) ,
83+ } ,
84+ ] ,
85+ } ,
86+ } ;
87+ } ,
88+ } ;
3389
3490const FadePreset : HeaderAnimationPreset = {
3591 styleInterpolator : ( { current, next } : InterpolationProps ) => {
36- const progress = next
37- ? multiply (
38- current ,
39- interpolate ( next , {
40- inputRange : [ 0 , 1 ] ,
41- outputRange : [ 1 , 0 ] ,
42- } )
43- )
44- : current ;
92+ const progress = add ( current , next ? next : 0 ) ;
93+ const opacity = interpolate ( progress , {
94+ inputRange : [ 0 , 1 , 2 ] ,
95+ outputRange : [ 0 , 1 , 0 ] ,
96+ } ) ;
4597
4698 return {
47- leftButtonStyle : { opacity : progress } ,
48- titleStyle : { opacity : progress } ,
99+ leftButtonStyle : { opacity } ,
100+ titleStyle : { opacity } ,
49101 } ;
50102 } ,
51103} ;
@@ -54,7 +106,7 @@ export default class HeaderAnimated<T extends Route> extends React.Component<
54106 Props < T >
55107> {
56108 static defaultProps = {
57- preset : FadePreset ,
109+ preset : Platform . OS === 'ios' ? UIKitPreset : FadePreset ,
58110 } ;
59111
60112 render ( ) {
0 commit comments