UIKonf 2014 - Building Better Transition

UIKonf 2014 - Building Better Transition

Build better transitions on iOS by standing on the shoulders of the disney animators by using their principles of animation. Also, animated transitions are selfish jerks because they block interaction so turn all your animated transitions into "interactive" animated transitions.

54f0de0b0bdee7e045c5a128c6ffeaf2?s=128

eallam

May 14, 2014
Tweet

Transcript

  1. Building Better Transitions By eric allam

  2. 1986

  3. Mimic Physical Reality in an interesting way

  4. None
  5. Transitions are high stakes

  6. principles of animation + iOS transition system

  7. Stretch and Squash. Timing. Anticipation. Staging. Follow-through and Overlapping Action.

    Straight Ahead Action and Pose-to-Pose Action. Slow in and Slow out. Arcs. Exaggeration. Secondary Action. Appeal.
  8. Timing Arcs & Appeal Staging

  9. Timing

  10. UIViewAnimationOptionCurve*

  11. Timing is: The velocity speed of an action

  12. Not too slow or too fast

  13. Too fast leads to strobing

  14. not just animateWithDuration:

  15. Speed = duration / distance

  16. None
  17. None
  18. Default Transition 0.5 seconds Spring Animation usingSpringWithDamping:10 initialSpringVelocity:0 Full Screen

  19. None
  20. Custom Modal Transition

  21. <UIViewControllerAnimatedTransitioning> - (NSTimeInterval)transitionDuration: (id<UIViewControllerContextTransitioning>)transitionContext - (void)animateTransition: (id<UIViewControllerContextTransitioning>)transitionContext

  22. transitionDuration: Tells the transition system how long the transition should

    take
  23. animateTransition: This is where you perform the transition's animation

  24. UIViewControllerContextTransitioning Gives you access to both the "from" and "to"

    controllers, as well as the "container" view
  25. UIView *fromView = [transitionContext viewControllerForKey:UITransitionContextFromViewControllerKey].view; UIView *toView = [transitionContext viewControllerForKey:UITransitionContextToViewControllerKey].view;

    UIView *container = [transitionContext containerView];
  26. None
  27. Add toView to containerView

  28. Set toView's initial state

  29. Animate to toView's final state

  30. Complete Transition

  31. [transitionContext completeTransition:YES];

  32. Example

  33. In animateTransition: toView.bounds = CGRectMake(0, 0, 280, 180); toView.center =

    CGPointMake(container.center.x, -90); [container addSubview:toView];
  34. [UIView animateWithDuration:duration animations:^{ toView.center = container.center; } completion:^(BOOL finished) {

    [transitionContext completeTransition:YES]; }];
  35. 200ms <= duration <= 500 ms

  36. Slow in and Slow Out

  37. Ease In and Ease Out

  38. Follow through

  39. Arcs

  40. Appeal

  41. Enter the 3rd Dimension

  42. CATransform3D

  43. CGAffineTransform + z axis

  44. transform.m34 = - 1.0 / 500.0;

  45. In animateTransition: UIView *container = [transitionContext containerView]; CATransform3D perspective =

    CATransform3DIdentity; perspective.m34 = - 1.0 / 500.0; container.layer.sublayerTransform = perspective;
  46. Rotate toView around x-axis toView.layer.anchorPoint = CGPointMake(0.5, 0); toView.layer.position =

    adjustedPosition; toView.layer.transform = CATransform3DMakeRotation(M_PI_4, 1.0, 0, 0);
  47. [UIView animateWithDuration:duration animations:^{ toView.layer.transform = CATransform3DIdentity; toView.layer.position = centerPosition; }

    completion:^(BOOL finished) { container.layer.sublayerTransform = CATransform3DIdentity; toView.layer.transform = CATransform3DIdentity; toView.layer.anchorPoint = CGPointMake(0.5, 0.5); toView.layer.position = container.center; [transitionContext completeTransition:YES]; }];
  48. Guidelines for 3D transitions · Reset anchor points, transform, and

    positions on completion · Add perspective using the container view's sublayerTransform · Spring animations generally don't look right
  49. Staging Present main idea clearly

  50. Presenting self.startingPoint = self.sharedView.center; self.startingBounds = self.sharedView.bounds; self.sharedView.center = [toView

    convertPoint:self.startingPoint fromView:fromView]; [toView addSubview:self.sharedView];
  51. Animate [UIView animateWithDuration:duration animations:^{ toView.center = container.center; self.sharedView.center = CGPointMake(140,

    90); self.sharedView.bounds = CGRectMake(0, 0, 100, 100); } completion:^(BOOL finished) { [transitionContext completeTransition:YES]; }];
  52. Dismissal animation [UIView animateWithDuration:duration animations:^{ fromView.center = CGPointMake(container.center.x, -90); self.sharedView.center

    = [fromView convertPoint:self.startingPoint fromView:toView]; self.sharedView.bounds = self.startingBounds; }
  53. Dismissal completion completion:^(BOOL finished) { self.sharedView.center = [toView convertPoint:self.sharedView.center fromView:fromView];

    [toView addSubview:self.sharedView]; [transitionContext completeTransition:YES]; }];
  54. 1. Store off shared views center/ bounds

  55. 2. Convert to the presented view's coordinate space and add

    to hierarchy
  56. 3. Animate

  57. 4. On dismissal, convert back to presenting view's coordinate space

    and hierarchy
  58. Bring your transitions to life

  59. Anticipation

  60. Overlapping Action

  61. Stretch and Squash

  62. Illusion of Life

  63. Principles of Traditional Animation applied to 3D Computer animation

  64. Fingers

  65. Animated transitions are selfish jerks

  66. [UIApplication beginIgnoringInteractionEvents]

  67. Learn this one simple trick...

  68. Turn animated transitions into interactive transitions

  69. [UIApplication beginIgnoringInteractionEvents]

  70. Take all the code in animateTransition:

  71. And put it in startInteractiveTransition:

  72. <UIViewControllerInteractiveTransitioning> - (void)startInteractiveTransition: (id <UIViewControllerContextTransitioning>) transitionContext;

  73. Normal interactive transition: Gesture -> Animation

  74. Interactive animated transition: Animation -> Gesture? - > Animation?

  75. UIPanGestureRecognizer *gesture = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(didPan:)]; [container addGestureRecognizer:gesture]; gesture.delegate

    = self;
  76. Allow interaction [UIView animateWithDuration:duration delay:0 options:UIViewAnimationOptionAllowUserInteraction animations:^{ toView.center = container.center;

    };
  77. UIViewAnimationOptionAllowUserInter action

  78. Use the finished param completion:^(BOOL finished) { if (finished){ [gesture.view

    removeGestureRecognizer:gesture]; [transitionContext finishInteractiveTransition]; [transitionContext completeTransition:YES]; } }]
  79. Cancel animations when pan begins CALayer *layer = toView.layer.presentationLayer; toView.center

    = layer.position; [toView.layer removeAllAnimations];
  80. Move view as pan changes CGPoint translation = [gesture translationInView:container];

    CGPoint viewCenter = toView.center; viewCenter.x += translation.x; viewCenter.y += translation.y; toView.center = viewCenter; [gesture setTranslation:CGPointZero inView:[self.context containerView]];
  81. Finish or cancel when pan ends if (shouldFinish) { [self.context

    finishInteractiveTransition]; // Animate to center }else{ [self.context cancelInteractiveTransition]; // Animate off screen }
  82. Complete transition BOOL completed = ![self.context transitionWasCancelled]; [self.context completeTransition:completed];

  83. UIViewAnimateionCurveEaseInOut

  84. Animation as physically degrading continuations of gestures?

  85. Animations don't have a "starting velocity" input

  86. spring animation initialSpringVelocity:?

  87. "For smooth start to the animation, match this value to

    the view’s velocity as it was prior to attachment"
  88. initalSpringVelocity:panVelocity

  89. pan velocity / animation distance

  90. UIKit Dynamics Facebook's POP Manually

  91. http://www.objc.io/issue-12/interactive- animations.html

  92. 1. Move code to startInteractiveTransition:

  93. 2. Allow user interaction

  94. 3. Remove animations when gesture begins

  95. 4. Finish or cancel when gesture ends

  96. 5. Animate to final position

  97. 6. Complete the transition

  98. Navigation transitions

  99. Update percent complete - updateInteractiveTransition:(CGFloat)percentComplete

  100. Use display link

  101. Create right before animation starts self.startTime = CACurrentMediaTime(); self.displayLink =

    [CADisplayLink displayLinkWithTarget:self selector:@selector(tick:)]; [self.displayLink addToRunLoop:[NSRunLoop mainRunLoop] forMode:NSRunLoopCommonModes];
  102. Calculate and update percent complete - (void)tick:(CADisplayLink *)link { CGFloat

    complete = (link.timestamp - self.startTime) / duration; [self.context updateInteractiveTransition:complete]; }
  103. Invalidate when animation ends or gesture begins [self.displayLink invalidate]

  104. Build better transitions by using the principles of animation, and

    always interactive transitions
  105. Thank you @eallam

  106. Credits The 12 Principles GIFs by Vincenzo Lodigiani the12principles.tumblr.com Banana

    Fingers Photo: flic.kr/p/9KUF1r "Transitional Interfaces" by Pasquale D'Silva "Animated UI Transitions and Perception of Time"