Commit 6007f6af authored by Matt Perry's avatar Matt Perry Committed by GitHub

Use fastOutSlowIn curve for transitions on iOS when not controlled by user gesture. (#5666)

BUG=https://github.com/flutter/flutter/issues/5599
parent ed6e7fa0
......@@ -48,13 +48,14 @@ class _CupertinoPageTransition extends AnimatedWidget {
_CupertinoPageTransition({
Key key,
Curve curve,
Animation<double> animation,
this.child
}) : super(
key: key,
animation: _kTween.animate(new CurvedAnimation(
parent: animation,
curve: new _CupertinoTransitionCurve()
curve: new _CupertinoTransitionCurve(curve)
)
));
......@@ -84,16 +85,33 @@ class AnimationMean extends CompoundAnimation<double> {
double get value => (first.value + next.value) / 2.0;
}
// Custom curve for iOS page transitions. The halfway point is when the page
// is fully on-screen. 0.0 is fully off-screen to the right. 1.0 is off-screen
// to the left.
// Custom curve for iOS page transitions.
class _CupertinoTransitionCurve extends Curve {
_CupertinoTransitionCurve();
_CupertinoTransitionCurve(this.curve);
Curve curve;
@override
double transform(double t) {
if (t > 0.5)
return (t - 0.5) / 3.0 + 0.5;
// The input [t] is the average of the current and next route's animation.
// This means t=0.5 represents when the route is fully onscreen. At
// t > 0.5, it is partially offscreen to the left (which happens when there
// is another route on top). At t < 0.5, the route is to the right.
// We divide the range into two halves, each with a different transition,
// and scale each half to the range [0.0, 1.0] before applying curves so that
// each half goes through the full range of the curve.
if (t > 0.5) {
// Route is to the left of center.
t = (t - 0.5) * 2.0;
if (curve != null)
t = curve.transform(t);
t = t / 3.0;
t = t / 2.0 + 0.5;
} else {
// Route is to the right of center.
if (curve != null)
t = curve.transform(t * 2.0) / 2.0;
}
return t;
}
}
......@@ -220,7 +238,8 @@ class MaterialPageRoute<T> extends PageRoute<T> {
// TODO(mpcomplete): This hack prevents the previousRoute from animating
// when we pop(). Remove once we fix this bug:
// https://github.com/flutter/flutter/issues/5577
if (!Navigator.of(context).userGestureInProgress)
bool userGesture = Navigator.of(context).userGestureInProgress;
if (!userGesture)
forwardAnimation = kAlwaysDismissedAnimation;
ThemeData theme = Theme.of(context);
......@@ -233,6 +252,10 @@ class MaterialPageRoute<T> extends PageRoute<T> {
);
case TargetPlatform.iOS:
return new _CupertinoPageTransition(
// Use a linear curve when controlled by a user gesture. This ensures
// the animation tracks the user's finger 1:1.
// See https://github.com/flutter/flutter/issues/5664
curve: userGesture ? null : Curves.fastOutSlowIn,
animation: new AnimationMean(left: animation, right: forwardAnimation),
child: child
);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment