Joe Cerra, UIKit Engineer - Apple Inc....•Advanced Animations with UIKit • Session 230 App...

281
#WWDC17 © 2017 Apple Inc. All rights reserved. Redistribution or public display not permitted without written permission from Apple. Joe Cerra, UIKit Engineer Advanced Animations with UIKit Session 230 App Frameworks

Transcript of Joe Cerra, UIKit Engineer - Apple Inc....•Advanced Animations with UIKit • Session 230 App...

Page 1: Joe Cerra, UIKit Engineer - Apple Inc....•Advanced Animations with UIKit • Session 230 App Frameworks • Basics • Interactive and Interruptible Animations • New Property Animator

#WWDC17

© 2017 Apple Inc. All rights reserved. Redistribution or public display not permitted without written permission from Apple.

Joe Cerra, UIKit Engineer

•Advanced Animations with UIKit • Session 230

App Frameworks

Page 2: Joe Cerra, UIKit Engineer - Apple Inc....•Advanced Animations with UIKit • Session 230 App Frameworks • Basics • Interactive and Interruptible Animations • New Property Animator

•Basics •Interactive and Interruptible Animations •New Property Animator Behaviors •Coordinating Animations •Tips and Tricks

Page 3: Joe Cerra, UIKit Engineer - Apple Inc....•Advanced Animations with UIKit • Session 230 App Frameworks • Basics • Interactive and Interruptible Animations • New Property Animator

•Basics •Interactive and Interruptible Animations •New Property Animator Behaviors •Coordinating Animations •Tips and Tricks

Page 4: Joe Cerra, UIKit Engineer - Apple Inc....•Advanced Animations with UIKit • Session 230 App Frameworks • Basics • Interactive and Interruptible Animations • New Property Animator

•Basics •Interactive and Interruptible Animations •New Property Animator Behaviors •Coordinating Animations •Tips and Tricks

Page 5: Joe Cerra, UIKit Engineer - Apple Inc....•Advanced Animations with UIKit • Session 230 App Frameworks • Basics • Interactive and Interruptible Animations • New Property Animator

•Basics •Interactive and Interruptible Animations •New Property Animator Behaviors •Coordinating Animations •Tips and Tricks

Page 6: Joe Cerra, UIKit Engineer - Apple Inc....•Advanced Animations with UIKit • Session 230 App Frameworks • Basics • Interactive and Interruptible Animations • New Property Animator

•Basics •Interactive and Interruptible Animations •New Property Animator Behaviors •Coordinating Animations •Tips and Tricks

Page 7: Joe Cerra, UIKit Engineer - Apple Inc....•Advanced Animations with UIKit • Session 230 App Frameworks • Basics • Interactive and Interruptible Animations • New Property Animator

•Basics

Page 8: Joe Cerra, UIKit Engineer - Apple Inc....•Advanced Animations with UIKit • Session 230 App Frameworks • Basics • Interactive and Interruptible Animations • New Property Animator

UIView-based Animations

Page 9: Joe Cerra, UIKit Engineer - Apple Inc....•Advanced Animations with UIKit • Session 230 App Frameworks • Basics • Interactive and Interruptible Animations • New Property Animator

UIView-based Animations

0 100x

Page 10: Joe Cerra, UIKit Engineer - Apple Inc....•Advanced Animations with UIKit • Session 230 App Frameworks • Basics • Interactive and Interruptible Animations • New Property Animator

UIView-based Animations

0 100x

UIView.animate(withDuration: 5) { circle.frame = circle.frame.offsetBy(dx: 100, dy: 0) }, completion: nil)

Page 11: Joe Cerra, UIKit Engineer - Apple Inc....•Advanced Animations with UIKit • Session 230 App Frameworks • Basics • Interactive and Interruptible Animations • New Property Animator

UIView-based Animations

0 100x

UIView.animate(withDuration: 5) { circle.frame = circle.frame.offsetBy(dx: 100, dy: 0) }, completion: nil)

Page 12: Joe Cerra, UIKit Engineer - Apple Inc....•Advanced Animations with UIKit • Session 230 App Frameworks • Basics • Interactive and Interruptible Animations • New Property Animator

UIView-based Animations

0 100x

UIView.animate(withDuration: 5) { circle.frame = circle.frame.offsetBy(dx: 100, dy: 0) }, completion: nil)

Page 13: Joe Cerra, UIKit Engineer - Apple Inc....•Advanced Animations with UIKit • Session 230 App Frameworks • Basics • Interactive and Interruptible Animations • New Property Animator

UIView-based Animations

0 100x

UIView.animate(withDuration: 5) { circle.frame = circle.frame.offsetBy(dx: 100, dy: 0) }, completion: nil)

Page 14: Joe Cerra, UIKit Engineer - Apple Inc....•Advanced Animations with UIKit • Session 230 App Frameworks • Basics • Interactive and Interruptible Animations • New Property Animator

UIView-based Animations

0 100x

UIView.animate(withDuration: 5) { circle.frame = circle.frame.offsetBy(dx: 100, dy: 0) }, completion: nil)

Page 15: Joe Cerra, UIKit Engineer - Apple Inc....•Advanced Animations with UIKit • Session 230 App Frameworks • Basics • Interactive and Interruptible Animations • New Property Animator

UIViewPropertyAnimator

Page 16: Joe Cerra, UIKit Engineer - Apple Inc....•Advanced Animations with UIKit • Session 230 App Frameworks • Basics • Interactive and Interruptible Animations • New Property Animator

UIViewPropertyAnimator Features

Custom timing

Interactive

Interruptible

Responsive

Page 17: Joe Cerra, UIKit Engineer - Apple Inc....•Advanced Animations with UIKit • Session 230 App Frameworks • Basics • Interactive and Interruptible Animations • New Property Animator

UIViewPropertyAnimator

0 100x

Page 18: Joe Cerra, UIKit Engineer - Apple Inc....•Advanced Animations with UIKit • Session 230 App Frameworks • Basics • Interactive and Interruptible Animations • New Property Animator

UIViewPropertyAnimator

let animator = UIViewPropertyAnimator(duration: 2.5, curve: .linear) { circle.frame = circle.frame.offsetBy(dx: 100, dy: 0) } animator.startAnimation()

0 100x

Page 19: Joe Cerra, UIKit Engineer - Apple Inc....•Advanced Animations with UIKit • Session 230 App Frameworks • Basics • Interactive and Interruptible Animations • New Property Animator

UIViewPropertyAnimator

let animator = UIViewPropertyAnimator(duration: 2.5, curve: .linear) { circle.frame = circle.frame.offsetBy(dx: 100, dy: 0) } animator.startAnimation()

0 100x

Page 20: Joe Cerra, UIKit Engineer - Apple Inc....•Advanced Animations with UIKit • Session 230 App Frameworks • Basics • Interactive and Interruptible Animations • New Property Animator

UIViewPropertyAnimator

let animator = UIViewPropertyAnimator(duration: 2.5, curve: .linear) { circle.frame = circle.frame.offsetBy(dx: 100, dy: 0) } animator.startAnimation()

0 100x

Page 21: Joe Cerra, UIKit Engineer - Apple Inc....•Advanced Animations with UIKit • Session 230 App Frameworks • Basics • Interactive and Interruptible Animations • New Property Animator

UIViewPropertyAnimator

let animator = UIViewPropertyAnimator(duration: 2.5, curve: .linear) { circle.frame = circle.frame.offsetBy(dx: 100, dy: 0) } animator.startAnimation()

0 100x

Page 22: Joe Cerra, UIKit Engineer - Apple Inc....•Advanced Animations with UIKit • Session 230 App Frameworks • Basics • Interactive and Interruptible Animations • New Property Animator

UIViewPropertyAnimator

let animator = UIViewPropertyAnimator(duration: 2.5, curve: .linear) { circle.frame = circle.frame.offsetBy(dx: 100, dy: 0) } animator.startAnimation()

0 100x

Page 23: Joe Cerra, UIKit Engineer - Apple Inc....•Advanced Animations with UIKit • Session 230 App Frameworks • Basics • Interactive and Interruptible Animations • New Property Animator

UIViewPropertyAnimator

let animator = UIViewPropertyAnimator(duration: 2.5, curve: .linear) { circle.frame = circle.frame.offsetBy(dx: 100, dy: 0) } animator.startAnimation()

0 100x

Page 24: Joe Cerra, UIKit Engineer - Apple Inc....•Advanced Animations with UIKit • Session 230 App Frameworks • Basics • Interactive and Interruptible Animations • New Property Animator

Timing Curves

Progress

Time

1.0

0.0 1.0

0.5

0.5

.linear

Page 25: Joe Cerra, UIKit Engineer - Apple Inc....•Advanced Animations with UIKit • Session 230 App Frameworks • Basics • Interactive and Interruptible Animations • New Property Animator

Linear Curves

Progress Time=% %

Page 26: Joe Cerra, UIKit Engineer - Apple Inc....•Advanced Animations with UIKit • Session 230 App Frameworks • Basics • Interactive and Interruptible Animations • New Property Animator

Progress 1.0

0.0 1.0

0.5

0.5 Time

Ease In Ease Out

.easeIn

1.0

0.0 1.0

0.5

0.5

.easeOut

Timing Curves

Page 27: Joe Cerra, UIKit Engineer - Apple Inc....•Advanced Animations with UIKit • Session 230 App Frameworks • Basics • Interactive and Interruptible Animations • New Property Animator

Progress

Custom Ease In

1.0

0.0 1.0

0.5

0.5

Custom Curves

Time

Page 28: Joe Cerra, UIKit Engineer - Apple Inc....•Advanced Animations with UIKit • Session 230 App Frameworks • Basics • Interactive and Interruptible Animations • New Property Animator

UICubicTimingParameters(controlPoint1: CGPoint(x: 0.75, y: 0.1), controlPoint2: CGPoint(x: 0.9, y: 0.25))

(0.75, 0.1)

(0.9, 0.25)

Custom Curves

Progress

Custom Ease In

1.0

0.0 1.0

0.5

0.5 Time

Page 29: Joe Cerra, UIKit Engineer - Apple Inc....•Advanced Animations with UIKit • Session 230 App Frameworks • Basics • Interactive and Interruptible Animations • New Property Animator

•Interactively Animating

Page 30: Joe Cerra, UIKit Engineer - Apple Inc....•Advanced Animations with UIKit • Session 230 App Frameworks • Basics • Interactive and Interruptible Animations • New Property Animator
Page 31: Joe Cerra, UIKit Engineer - Apple Inc....•Advanced Animations with UIKit • Session 230 App Frameworks • Basics • Interactive and Interruptible Animations • New Property Animator
Page 32: Joe Cerra, UIKit Engineer - Apple Inc....•Advanced Animations with UIKit • Session 230 App Frameworks • Basics • Interactive and Interruptible Animations • New Property Animator
Page 33: Joe Cerra, UIKit Engineer - Apple Inc....•Advanced Animations with UIKit • Session 230 App Frameworks • Basics • Interactive and Interruptible Animations • New Property Animator
Page 34: Joe Cerra, UIKit Engineer - Apple Inc....•Advanced Animations with UIKit • Session 230 App Frameworks • Basics • Interactive and Interruptible Animations • New Property Animator

Interactively animating

0 100x

Page 35: Joe Cerra, UIKit Engineer - Apple Inc....•Advanced Animations with UIKit • Session 230 App Frameworks • Basics • Interactive and Interruptible Animations • New Property Animator

Interactively animating

0 100x

UIPanGestureRecognizer

Page 36: Joe Cerra, UIKit Engineer - Apple Inc....•Advanced Animations with UIKit • Session 230 App Frameworks • Basics • Interactive and Interruptible Animations • New Property Animator

Interactively animating

0 100x

Page 37: Joe Cerra, UIKit Engineer - Apple Inc....•Advanced Animations with UIKit • Session 230 App Frameworks • Basics • Interactive and Interruptible Animations • New Property Animator

Interactively animating

0 100x

Page 38: Joe Cerra, UIKit Engineer - Apple Inc....•Advanced Animations with UIKit • Session 230 App Frameworks • Basics • Interactive and Interruptible Animations • New Property Animator

Interactively animating

0 100x

Page 39: Joe Cerra, UIKit Engineer - Apple Inc....•Advanced Animations with UIKit • Session 230 App Frameworks • Basics • Interactive and Interruptible Animations • New Property Animator

Interactively animating

0 100x

Page 40: Joe Cerra, UIKit Engineer - Apple Inc....•Advanced Animations with UIKit • Session 230 App Frameworks • Basics • Interactive and Interruptible Animations • New Property Animator

Interactively animating

0 100x

Page 41: Joe Cerra, UIKit Engineer - Apple Inc....•Advanced Animations with UIKit • Session 230 App Frameworks • Basics • Interactive and Interruptible Animations • New Property Animator

Interactively animating

0 100x

Page 42: Joe Cerra, UIKit Engineer - Apple Inc....•Advanced Animations with UIKit • Session 230 App Frameworks • Basics • Interactive and Interruptible Animations • New Property Animator

var animator: UIViewPropertyAnimator!

func handlePan(recognizer: UIPanGestureRecognizer) { switch recognizer.state { case .began: animator = UIViewPropertyAnimator(duration: 1, curve: .easeOut, animations: { circle.frame = circle.frame.offsetBy(dx: 100, dy: 0) }) animator.pauseAnimation() case .changed: let translation = recognizer.translation(in: circle) animator.fractionComplete = translation.x / 100 case .ended: animator.continueAnimation(withTimingParameters: nil, durationFactor: 0) } }

Page 43: Joe Cerra, UIKit Engineer - Apple Inc....•Advanced Animations with UIKit • Session 230 App Frameworks • Basics • Interactive and Interruptible Animations • New Property Animator

var animator: UIViewPropertyAnimator!

func handlePan(recognizer: UIPanGestureRecognizer) { switch recognizer.state { case .began: animator = UIViewPropertyAnimator(duration: 1, curve: .easeOut, animations: { circle.frame = circle.frame.offsetBy(dx: 100, dy: 0) }) animator.pauseAnimation() case .changed: let translation = recognizer.translation(in: circle) animator.fractionComplete = translation.x / 100 case .ended: animator.continueAnimation(withTimingParameters: nil, durationFactor: 0) } }

Page 44: Joe Cerra, UIKit Engineer - Apple Inc....•Advanced Animations with UIKit • Session 230 App Frameworks • Basics • Interactive and Interruptible Animations • New Property Animator

var animator: UIViewPropertyAnimator!

func handlePan(recognizer: UIPanGestureRecognizer) { switch recognizer.state { case .began: animator = UIViewPropertyAnimator(duration: 1, curve: .easeOut, animations: { circle.frame = circle.frame.offsetBy(dx: 100, dy: 0) }) animator.pauseAnimation() case .changed: let translation = recognizer.translation(in: circle) animator.fractionComplete = translation.x / 100 case .ended: animator.continueAnimation(withTimingParameters: nil, durationFactor: 0) } }

Page 45: Joe Cerra, UIKit Engineer - Apple Inc....•Advanced Animations with UIKit • Session 230 App Frameworks • Basics • Interactive and Interruptible Animations • New Property Animator

var animator: UIViewPropertyAnimator!

func handlePan(recognizer: UIPanGestureRecognizer) { switch recognizer.state { case .began: animator = UIViewPropertyAnimator(duration: 1, curve: .easeOut, animations: { circle.frame = circle.frame.offsetBy(dx: 100, dy: 0) }) animator.pauseAnimation() case .changed: let translation = recognizer.translation(in: circle) animator.fractionComplete = translation.x / 100 case .ended: animator.continueAnimation(withTimingParameters: nil, durationFactor: 0) } }

Page 46: Joe Cerra, UIKit Engineer - Apple Inc....•Advanced Animations with UIKit • Session 230 App Frameworks • Basics • Interactive and Interruptible Animations • New Property Animator

var animator: UIViewPropertyAnimator!

func handlePan(recognizer: UIPanGestureRecognizer) { switch recognizer.state { case .began: animator = UIViewPropertyAnimator(duration: 1, curve: .easeOut, animations: { circle.frame = circle.frame.offsetBy(dx: 100, dy: 0) }) animator.pauseAnimation() case .changed: let translation = recognizer.translation(in: circle) animator.fractionComplete = translation.x / 100 case .ended: animator.continueAnimation(withTimingParameters: nil, durationFactor: 0) } }

Page 47: Joe Cerra, UIKit Engineer - Apple Inc....•Advanced Animations with UIKit • Session 230 App Frameworks • Basics • Interactive and Interruptible Animations • New Property Animator

var animator: UIViewPropertyAnimator!

func handlePan(recognizer: UIPanGestureRecognizer) { switch recognizer.state { case .began: animator = UIViewPropertyAnimator(duration: 1, curve: .easeOut, animations: { circle.frame = circle.frame.offsetBy(dx: 100, dy: 0) }) animator.pauseAnimation() case .changed: let translation = recognizer.translation(in: circle) animator.fractionComplete = translation.x / 100 case .ended: animator.continueAnimation(withTimingParameters: nil, durationFactor: 0) } }

Page 48: Joe Cerra, UIKit Engineer - Apple Inc....•Advanced Animations with UIKit • Session 230 App Frameworks • Basics • Interactive and Interruptible Animations • New Property Animator

Time Conversion

Pausing

Continuing

Page 49: Joe Cerra, UIKit Engineer - Apple Inc....•Advanced Animations with UIKit • Session 230 App Frameworks • Basics • Interactive and Interruptible Animations • New Property Animator

Time Conversion

Pausing

ContinuingContinuing

Page 50: Joe Cerra, UIKit Engineer - Apple Inc....•Advanced Animations with UIKit • Session 230 App Frameworks • Basics • Interactive and Interruptible Animations • New Property Animator

UIViewPropertyAnimator(duration: 1, curve: .easeOut)

animationState .inactive

running false

fractionComplete 0%

Progress

Time

1.0

0.0 1.0

0.5

0.5

Page 51: Joe Cerra, UIKit Engineer - Apple Inc....•Advanced Animations with UIKit • Session 230 App Frameworks • Basics • Interactive and Interruptible Animations • New Property Animator

1.0

0.0 1.0

0.5

0.5

animator.pauseAnimation()

Progress

Time

animationState .active

running false

fractionComplete 0%

Page 52: Joe Cerra, UIKit Engineer - Apple Inc....•Advanced Animations with UIKit • Session 230 App Frameworks • Basics • Interactive and Interruptible Animations • New Property Animator

1.0

0.0 1.0

0.5

0.5

animator.pauseAnimation()

Progress

Time

animationState .active

running false

fractionComplete 0%

Page 53: Joe Cerra, UIKit Engineer - Apple Inc....•Advanced Animations with UIKit • Session 230 App Frameworks • Basics • Interactive and Interruptible Animations • New Property Animator

Time Conversion

Pausing

Continuing

Page 54: Joe Cerra, UIKit Engineer - Apple Inc....•Advanced Animations with UIKit • Session 230 App Frameworks • Basics • Interactive and Interruptible Animations • New Property Animator

1.0

0.0 1.0

0.5

0.5

animator.fractionComplete = translation.x / distance

Progress

Time

Page 55: Joe Cerra, UIKit Engineer - Apple Inc....•Advanced Animations with UIKit • Session 230 App Frameworks • Basics • Interactive and Interruptible Animations • New Property Animator

1.0

0.0 1.0

0.5

0.5

animator.fractionComplete = translation.x / distance

Progress

Time

Page 56: Joe Cerra, UIKit Engineer - Apple Inc....•Advanced Animations with UIKit • Session 230 App Frameworks • Basics • Interactive and Interruptible Animations • New Property Animator

1.0

0.0 1.0

0.5

0.5

animator.fractionComplete = translation.x / distance

fractionComplete 50%

running false

animationState .active

Progress

Time

Page 57: Joe Cerra, UIKit Engineer - Apple Inc....•Advanced Animations with UIKit • Session 230 App Frameworks • Basics • Interactive and Interruptible Animations • New Property Animator

1.0

0.0 1.0

0.5

0.5

animator.continueAnimation(withTimingParameters: nil, durationFactor: 0)

Progress

Time

Page 58: Joe Cerra, UIKit Engineer - Apple Inc....•Advanced Animations with UIKit • Session 230 App Frameworks • Basics • Interactive and Interruptible Animations • New Property Animator

1.0

0.0 1.0

0.5

0.5

animator.continueAnimation(withTimingParameters: nil, durationFactor: 0)

running true

fractionComplete 50%

animationState .active

Progress

Time

Page 59: Joe Cerra, UIKit Engineer - Apple Inc....•Advanced Animations with UIKit • Session 230 App Frameworks • Basics • Interactive and Interruptible Animations • New Property Animator

1.0

0.0 1.0

0.5

0.5

Progress

Time

animator.continueAnimation(withTimingParameters: nil, durationFactor: 0)

running true

fractionComplete 10%

animationState .active

Page 60: Joe Cerra, UIKit Engineer - Apple Inc....•Advanced Animations with UIKit • Session 230 App Frameworks • Basics • Interactive and Interruptible Animations • New Property Animator

1.0

0.0 1.0

0.5

0.5

Progress

Time

animator.continueAnimation(withTimingParameters: nil, durationFactor: 0)

running true

fractionComplete 10%

animationState .active

Page 61: Joe Cerra, UIKit Engineer - Apple Inc....•Advanced Animations with UIKit • Session 230 App Frameworks • Basics • Interactive and Interruptible Animations • New Property Animator

1.0

0.0 1.0

0.5

0.5

Progress

Time

animator.continueAnimation(withTimingParameters: nil, durationFactor: 0)

90%

Page 62: Joe Cerra, UIKit Engineer - Apple Inc....•Advanced Animations with UIKit • Session 230 App Frameworks • Basics • Interactive and Interruptible Animations • New Property Animator

animator.continueAnimation(withTimingParameters: nil, durationFactor: 0)

Duration 2 seconds

1.0

0.0 1.0

0.5

0.5

Progress

Time

90%

Page 63: Joe Cerra, UIKit Engineer - Apple Inc....•Advanced Animations with UIKit • Session 230 App Frameworks • Basics • Interactive and Interruptible Animations • New Property Animator

animator.continueAnimation(withTimingParameters: nil, durationFactor: 0)

Remaining time 1.8 seconds

Duration 2 seconds

1.0

0.0 1.0

0.5

0.5

Progress

Time

90%

Page 64: Joe Cerra, UIKit Engineer - Apple Inc....•Advanced Animations with UIKit • Session 230 App Frameworks • Basics • Interactive and Interruptible Animations • New Property Animator

•Interruptible Animations

Page 65: Joe Cerra, UIKit Engineer - Apple Inc....•Advanced Animations with UIKit • Session 230 App Frameworks • Basics • Interactive and Interruptible Animations • New Property Animator
Page 66: Joe Cerra, UIKit Engineer - Apple Inc....•Advanced Animations with UIKit • Session 230 App Frameworks • Basics • Interactive and Interruptible Animations • New Property Animator
Page 67: Joe Cerra, UIKit Engineer - Apple Inc....•Advanced Animations with UIKit • Session 230 App Frameworks • Basics • Interactive and Interruptible Animations • New Property Animator
Page 68: Joe Cerra, UIKit Engineer - Apple Inc....•Advanced Animations with UIKit • Session 230 App Frameworks • Basics • Interactive and Interruptible Animations • New Property Animator
Page 69: Joe Cerra, UIKit Engineer - Apple Inc....•Advanced Animations with UIKit • Session 230 App Frameworks • Basics • Interactive and Interruptible Animations • New Property Animator
Page 70: Joe Cerra, UIKit Engineer - Apple Inc....•Advanced Animations with UIKit • Session 230 App Frameworks • Basics • Interactive and Interruptible Animations • New Property Animator
Page 71: Joe Cerra, UIKit Engineer - Apple Inc....•Advanced Animations with UIKit • Session 230 App Frameworks • Basics • Interactive and Interruptible Animations • New Property Animator

Interrupting an Animation

0 100x

Page 72: Joe Cerra, UIKit Engineer - Apple Inc....•Advanced Animations with UIKit • Session 230 App Frameworks • Basics • Interactive and Interruptible Animations • New Property Animator

Interrupting an Animation

0 100x

UIPanGestureRecognizer

Page 73: Joe Cerra, UIKit Engineer - Apple Inc....•Advanced Animations with UIKit • Session 230 App Frameworks • Basics • Interactive and Interruptible Animations • New Property Animator

Interrupting an Animation

0 100x

Page 74: Joe Cerra, UIKit Engineer - Apple Inc....•Advanced Animations with UIKit • Session 230 App Frameworks • Basics • Interactive and Interruptible Animations • New Property Animator

Interrupting an Animation

0 100x

Page 75: Joe Cerra, UIKit Engineer - Apple Inc....•Advanced Animations with UIKit • Session 230 App Frameworks • Basics • Interactive and Interruptible Animations • New Property Animator

Interrupting an Animation

0 100x

Page 76: Joe Cerra, UIKit Engineer - Apple Inc....•Advanced Animations with UIKit • Session 230 App Frameworks • Basics • Interactive and Interruptible Animations • New Property Animator

Interrupting an Animation

0 100x

Page 77: Joe Cerra, UIKit Engineer - Apple Inc....•Advanced Animations with UIKit • Session 230 App Frameworks • Basics • Interactive and Interruptible Animations • New Property Animator

Interrupting an Animation

0 100x

Page 78: Joe Cerra, UIKit Engineer - Apple Inc....•Advanced Animations with UIKit • Session 230 App Frameworks • Basics • Interactive and Interruptible Animations • New Property Animator

Interrupting an Animation

0 100x

Page 79: Joe Cerra, UIKit Engineer - Apple Inc....•Advanced Animations with UIKit • Session 230 App Frameworks • Basics • Interactive and Interruptible Animations • New Property Animator

func animateTransitionIfNeeded(duration: TimeInterval) {...}

var progressWhenInterrupted: CGFloat = 0

func handlePan(recognizer: UIPanGestureRecognizer) { switch recognizer.state { case .began: animateTransitionIfNeeded(duration: 1) animator.pauseAnimation() progressWhenInterrupted = animator.fractionComplete case .changed: let translation = recognizer.translation(in: circle) animator.fractionComplete = (translation.x / 100) + progressWhenInterrupted case .ended: let timing = UICubicTimingParameters(animationCurve: .easeOut) animator.continueAnimation(withTimingParameters: timing, durationFactor: 0) } }

Page 80: Joe Cerra, UIKit Engineer - Apple Inc....•Advanced Animations with UIKit • Session 230 App Frameworks • Basics • Interactive and Interruptible Animations • New Property Animator

func animateTransitionIfNeeded(duration: TimeInterval) {...}

var progressWhenInterrupted: CGFloat = 0

func handlePan(recognizer: UIPanGestureRecognizer) { switch recognizer.state { case .began: animateTransitionIfNeeded(duration: 1) animator.pauseAnimation() progressWhenInterrupted = animator.fractionComplete case .changed: let translation = recognizer.translation(in: circle) animator.fractionComplete = (translation.x / 100) + progressWhenInterrupted case .ended: let timing = UICubicTimingParameters(animationCurve: .easeOut) animator.continueAnimation(withTimingParameters: timing, durationFactor: 0) } }

Page 81: Joe Cerra, UIKit Engineer - Apple Inc....•Advanced Animations with UIKit • Session 230 App Frameworks • Basics • Interactive and Interruptible Animations • New Property Animator

func animateTransitionIfNeeded(duration: TimeInterval) {...}

var progressWhenInterrupted: CGFloat = 0

func handlePan(recognizer: UIPanGestureRecognizer) { switch recognizer.state { case .began: animateTransitionIfNeeded(duration: 1) animator.pauseAnimation() progressWhenInterrupted = animator.fractionComplete case .changed: let translation = recognizer.translation(in: circle) animator.fractionComplete = (translation.x / 100) + progressWhenInterrupted case .ended: let timing = UICubicTimingParameters(animationCurve: .easeOut) animator.continueAnimation(withTimingParameters: timing, durationFactor: 0) } }

Page 82: Joe Cerra, UIKit Engineer - Apple Inc....•Advanced Animations with UIKit • Session 230 App Frameworks • Basics • Interactive and Interruptible Animations • New Property Animator

func animateTransitionIfNeeded(duration: TimeInterval) {...}

var progressWhenInterrupted: CGFloat = 0

func handlePan(recognizer: UIPanGestureRecognizer) { switch recognizer.state { case .began: animateTransitionIfNeeded(duration: 1) animator.pauseAnimation() progressWhenInterrupted = animator.fractionComplete case .changed: let translation = recognizer.translation(in: circle) animator.fractionComplete = (translation.x / 100) + progressWhenInterrupted case .ended: let timing = UICubicTimingParameters(animationCurve: .easeOut) animator.continueAnimation(withTimingParameters: timing, durationFactor: 0) } }

Page 83: Joe Cerra, UIKit Engineer - Apple Inc....•Advanced Animations with UIKit • Session 230 App Frameworks • Basics • Interactive and Interruptible Animations • New Property Animator

func animateTransitionIfNeeded(duration: TimeInterval) {...}

var progressWhenInterrupted: CGFloat = 0

func handlePan(recognizer: UIPanGestureRecognizer) { switch recognizer.state { case .began: animateTransitionIfNeeded(duration: 1) animator.pauseAnimation() progressWhenInterrupted = animator.fractionComplete case .changed: let translation = recognizer.translation(in: circle) animator.fractionComplete = (translation.x / 100) + progressWhenInterrupted case .ended: let timing = UICubicTimingParameters(animationCurve: .easeOut) animator.continueAnimation(withTimingParameters: timing, durationFactor: 0) } }

Page 84: Joe Cerra, UIKit Engineer - Apple Inc....•Advanced Animations with UIKit • Session 230 App Frameworks • Basics • Interactive and Interruptible Animations • New Property Animator

func animateTransitionIfNeeded(duration: TimeInterval) {...}

var progressWhenInterrupted: CGFloat = 0

func handlePan(recognizer: UIPanGestureRecognizer) { switch recognizer.state { case .began: animateTransitionIfNeeded(duration: 1) animator.pauseAnimation() progressWhenInterrupted = animator.fractionComplete case .changed: let translation = recognizer.translation(in: circle) animator.fractionComplete = (translation.x / 100) + progressWhenInterrupted case .ended: let timing = UICubicTimingParameters(animationCurve: .easeOut) animator.continueAnimation(withTimingParameters: timing, durationFactor: 0) } }

Page 85: Joe Cerra, UIKit Engineer - Apple Inc....•Advanced Animations with UIKit • Session 230 App Frameworks • Basics • Interactive and Interruptible Animations • New Property Animator

Time Conversion

Pausing

Continuing

Page 86: Joe Cerra, UIKit Engineer - Apple Inc....•Advanced Animations with UIKit • Session 230 App Frameworks • Basics • Interactive and Interruptible Animations • New Property Animator

1.0

0.0 1.0

0.5

Time0.5

animator.isRunning

running false

fractionComplete 50%

animationState .active

Progress

Page 87: Joe Cerra, UIKit Engineer - Apple Inc....•Advanced Animations with UIKit • Session 230 App Frameworks • Basics • Interactive and Interruptible Animations • New Property Animator

1.0

0.0 1.0

0.5

Time0.5

animator.pauseAnimation()

Progress

Page 88: Joe Cerra, UIKit Engineer - Apple Inc....•Advanced Animations with UIKit • Session 230 App Frameworks • Basics • Interactive and Interruptible Animations • New Property Animator

1.0

0.0 1.0

0.5

Progress

Time0.5

animator.pauseAnimation()

running false

fractionComplete 50%

animationState .active

Page 89: Joe Cerra, UIKit Engineer - Apple Inc....•Advanced Animations with UIKit • Session 230 App Frameworks • Basics • Interactive and Interruptible Animations • New Property Animator

animator.pauseAnimation()

1.0

0.0 1.0

0.5

Progress

Time0.5

fractionComplete 10%

animationState .active

running false

Page 90: Joe Cerra, UIKit Engineer - Apple Inc....•Advanced Animations with UIKit • Session 230 App Frameworks • Basics • Interactive and Interruptible Animations • New Property Animator

animator.pauseAnimation()

1.0

0.0 1.0

0.5

Progress

Time0.5

fractionComplete 10%

animationState .active

running false

Page 91: Joe Cerra, UIKit Engineer - Apple Inc....•Advanced Animations with UIKit • Session 230 App Frameworks • Basics • Interactive and Interruptible Animations • New Property Animator

animator.fractionComplete = 0.1

1.0

0.0 1.0

0.5

Progress

Time0.5

fractionComplete 10%

animationState .active

running false

Page 92: Joe Cerra, UIKit Engineer - Apple Inc....•Advanced Animations with UIKit • Session 230 App Frameworks • Basics • Interactive and Interruptible Animations • New Property Animator

animator.continueAnimation(... animationCurve: .easeOut ...)

1.0

0.0 1.0

0.5

Progress

Time0.5

Page 93: Joe Cerra, UIKit Engineer - Apple Inc....•Advanced Animations with UIKit • Session 230 App Frameworks • Basics • Interactive and Interruptible Animations • New Property Animator

animator.continueAnimation(... animationCurve: .easeOut ...)

1.0

0.0 1.0

0.5

Progress

Time0.5

fractionComplete 10%

animationState .active

running true

Page 94: Joe Cerra, UIKit Engineer - Apple Inc....•Advanced Animations with UIKit • Session 230 App Frameworks • Basics • Interactive and Interruptible Animations • New Property Animator

animator.continueAnimation(... animationCurve: .easeOut ...)

1.0

0.0 1.0

0.5

Progress

Time0.5

fractionComplete 5%

animationState .active

running true

Page 95: Joe Cerra, UIKit Engineer - Apple Inc....•Advanced Animations with UIKit • Session 230 App Frameworks • Basics • Interactive and Interruptible Animations • New Property Animator

animator.continueAnimation(... animationCurve: .easeOut ...)

1.0

0.0 1.0

0.5

Progress

Time0.5

fractionComplete 5%

animationState .active

running true

Page 96: Joe Cerra, UIKit Engineer - Apple Inc....•Advanced Animations with UIKit • Session 230 App Frameworks • Basics • Interactive and Interruptible Animations • New Property Animator

•New Animator Behaviors

Page 97: Joe Cerra, UIKit Engineer - Apple Inc....•Advanced Animations with UIKit • Session 230 App Frameworks • Basics • Interactive and Interruptible Animations • New Property Animator

UIViewPropertyAnimator New in iOS 11

NEW

Page 98: Joe Cerra, UIKit Engineer - Apple Inc....•Advanced Animations with UIKit • Session 230 App Frameworks • Basics • Interactive and Interruptible Animations • New Property Animator

UIViewPropertyAnimator New in iOS 11

var scrubsLinearly: Bool var pausesOnCompletion: Bool

NEW

Page 99: Joe Cerra, UIKit Engineer - Apple Inc....•Advanced Animations with UIKit • Session 230 App Frameworks • Basics • Interactive and Interruptible Animations • New Property Animator

UIViewPropertyAnimator New in iOS 11

Starting as Paused

NEW

var scrubsLinearly: Bool var pausesOnCompletion: Bool

Page 100: Joe Cerra, UIKit Engineer - Apple Inc....•Advanced Animations with UIKit • Session 230 App Frameworks • Basics • Interactive and Interruptible Animations • New Property Animator

.scrubsLinearly Non-linear scrubbing

linear scrubbing

non-linear scrubbing

NEW

Page 101: Joe Cerra, UIKit Engineer - Apple Inc....•Advanced Animations with UIKit • Session 230 App Frameworks • Basics • Interactive and Interruptible Animations • New Property Animator

.scrubsLinearly Non-linear scrubbing

linear scrubbing

non-linear scrubbing

NEW

Page 102: Joe Cerra, UIKit Engineer - Apple Inc....•Advanced Animations with UIKit • Session 230 App Frameworks • Basics • Interactive and Interruptible Animations • New Property Animator

.scrubsLinearly Non-linear scrubbing

linear scrubbing

non-linear scrubbing

NEW

Page 103: Joe Cerra, UIKit Engineer - Apple Inc....•Advanced Animations with UIKit • Session 230 App Frameworks • Basics • Interactive and Interruptible Animations • New Property Animator

.scrubsLinearly Non-linear scrubbing

linear scrubbing

non-linear scrubbing

NEW

Page 104: Joe Cerra, UIKit Engineer - Apple Inc....•Advanced Animations with UIKit • Session 230 App Frameworks • Basics • Interactive and Interruptible Animations • New Property Animator

.pausesOnCompletion

.Inactive

.Active

Start / pause

Animations finish

NEW

Page 105: Joe Cerra, UIKit Engineer - Apple Inc....•Advanced Animations with UIKit • Session 230 App Frameworks • Basics • Interactive and Interruptible Animations • New Property Animator

.Inactive

Animations finish

.pausesOnCompletion

.Active

Start / pause

animator.pausesOnCompletion = true

NEW

Page 106: Joe Cerra, UIKit Engineer - Apple Inc....•Advanced Animations with UIKit • Session 230 App Frameworks • Basics • Interactive and Interruptible Animations • New Property Animator
Page 107: Joe Cerra, UIKit Engineer - Apple Inc....•Advanced Animations with UIKit • Session 230 App Frameworks • Basics • Interactive and Interruptible Animations • New Property Animator
Page 108: Joe Cerra, UIKit Engineer - Apple Inc....•Advanced Animations with UIKit • Session 230 App Frameworks • Basics • Interactive and Interruptible Animations • New Property Animator
Page 109: Joe Cerra, UIKit Engineer - Apple Inc....•Advanced Animations with UIKit • Session 230 App Frameworks • Basics • Interactive and Interruptible Animations • New Property Animator
Page 110: Joe Cerra, UIKit Engineer - Apple Inc....•Advanced Animations with UIKit • Session 230 App Frameworks • Basics • Interactive and Interruptible Animations • New Property Animator
Page 111: Joe Cerra, UIKit Engineer - Apple Inc....•Advanced Animations with UIKit • Session 230 App Frameworks • Basics • Interactive and Interruptible Animations • New Property Animator
Page 112: Joe Cerra, UIKit Engineer - Apple Inc....•Advanced Animations with UIKit • Session 230 App Frameworks • Basics • Interactive and Interruptible Animations • New Property Animator
Page 113: Joe Cerra, UIKit Engineer - Apple Inc....•Advanced Animations with UIKit • Session 230 App Frameworks • Basics • Interactive and Interruptible Animations • New Property Animator
Page 114: Joe Cerra, UIKit Engineer - Apple Inc....•Advanced Animations with UIKit • Session 230 App Frameworks • Basics • Interactive and Interruptible Animations • New Property Animator

.Inactive

Animations finish

.pausesOnCompletion

.Active

Start / pause

Page 115: Joe Cerra, UIKit Engineer - Apple Inc....•Advanced Animations with UIKit • Session 230 App Frameworks • Basics • Interactive and Interruptible Animations • New Property Animator

.Inactive

Animations finish

.pausesOnCompletion

.Active

Start / pause

animator.addObserver(self, forKeyPath: "running", options: [.new], context: nil)

Page 116: Joe Cerra, UIKit Engineer - Apple Inc....•Advanced Animations with UIKit • Session 230 App Frameworks • Basics • Interactive and Interruptible Animations • New Property Animator

Starting as Paused

let animator = UIViewPropertyAnimator(duration: 1, curve: .easeIn) animator.startAnimation() // ... animator.addAnimations { // will run immediately circle.frame = circle.frame.offsetBy(dx: 100, dy: 0) }

No escaping for animation blocks

NEW

Page 117: Joe Cerra, UIKit Engineer - Apple Inc....•Advanced Animations with UIKit • Session 230 App Frameworks • Basics • Interactive and Interruptible Animations • New Property Animator

•Springs

Page 118: Joe Cerra, UIKit Engineer - Apple Inc....•Advanced Animations with UIKit • Session 230 App Frameworks • Basics • Interactive and Interruptible Animations • New Property Animator

Spring Animations

Critically damped spring

Under damped spring

Page 119: Joe Cerra, UIKit Engineer - Apple Inc....•Advanced Animations with UIKit • Session 230 App Frameworks • Basics • Interactive and Interruptible Animations • New Property Animator

Spring Animations

Critically damped spring

Under damped spring

Page 120: Joe Cerra, UIKit Engineer - Apple Inc....•Advanced Animations with UIKit • Session 230 App Frameworks • Basics • Interactive and Interruptible Animations • New Property Animator

Spring Animations

Critically damped spring

Under damped spring

Page 121: Joe Cerra, UIKit Engineer - Apple Inc....•Advanced Animations with UIKit • Session 230 App Frameworks • Basics • Interactive and Interruptible Animations • New Property Animator

Spring Animations

Critically damped spring

Under damped spring

Page 122: Joe Cerra, UIKit Engineer - Apple Inc....•Advanced Animations with UIKit • Session 230 App Frameworks • Basics • Interactive and Interruptible Animations • New Property Animator

Spring Animations

Critically damped spring

Under damped spring

Page 123: Joe Cerra, UIKit Engineer - Apple Inc....•Advanced Animations with UIKit • Session 230 App Frameworks • Basics • Interactive and Interruptible Animations • New Property Animator

Spring Animations

Critically damped spring

Under damped spring

Page 124: Joe Cerra, UIKit Engineer - Apple Inc....•Advanced Animations with UIKit • Session 230 App Frameworks • Basics • Interactive and Interruptible Animations • New Property Animator

Spring Animations

Time

1.0

0.0 1.0

0.5

Progress

0.5

Critically damped spring Under damped springDamping ratio = 1.0 Damping ratio < 1.0

1.0

0.0 1.0

0.5

0.5

Page 125: Joe Cerra, UIKit Engineer - Apple Inc....•Advanced Animations with UIKit • Session 230 App Frameworks • Basics • Interactive and Interruptible Animations • New Property Animator

Spring Animations Why they always animate from current state

Page 126: Joe Cerra, UIKit Engineer - Apple Inc....•Advanced Animations with UIKit • Session 230 App Frameworks • Basics • Interactive and Interruptible Animations • New Property Animator

1.0

0.0 1.0

0.5

Time0.5

Spring Animations Why they always animate from current state

Remapping onto cubic may be undefined

1.0

0.0 1.0

0.5

0.5

Progress

Page 127: Joe Cerra, UIKit Engineer - Apple Inc....•Advanced Animations with UIKit • Session 230 App Frameworks • Basics • Interactive and Interruptible Animations • New Property Animator

1.0

0.0 1.0

0.5

Time0.5

Spring Animations Why they always animate from current state

1.0

0.0 1.0

0.5

0.5

position.x position.y

2D velocity desynchronization

Progress

Page 128: Joe Cerra, UIKit Engineer - Apple Inc....•Advanced Animations with UIKit • Session 230 App Frameworks • Basics • Interactive and Interruptible Animations • New Property Animator

1.0

0.0 1.0

0.5

Time0.5

Spring Animations Why they always animate from current state

1.0

0.0 1.0

0.5

0.5

position.x position.y

2D velocity desynchronization

Progress

Page 129: Joe Cerra, UIKit Engineer - Apple Inc....•Advanced Animations with UIKit • Session 230 App Frameworks • Basics • Interactive and Interruptible Animations • New Property Animator

Best Practices When Interrupting Springs

Page 130: Joe Cerra, UIKit Engineer - Apple Inc....•Advanced Animations with UIKit • Session 230 App Frameworks • Basics • Interactive and Interruptible Animations • New Property Animator

Best Practices When Interrupting Springs

Stop and create a new property animator

Page 131: Joe Cerra, UIKit Engineer - Apple Inc....•Advanced Animations with UIKit • Session 230 App Frameworks • Basics • Interactive and Interruptible Animations • New Property Animator

Best Practices When Interrupting Springs

Stop and create a new property animator

Use critically damped spring without velocity

Page 132: Joe Cerra, UIKit Engineer - Apple Inc....•Advanced Animations with UIKit • Session 230 App Frameworks • Basics • Interactive and Interruptible Animations • New Property Animator

Best Practices When Interrupting Springs

Stop and create a new property animator

Use critically damped spring without velocity

Decompose component velocity with multiple animators

Page 133: Joe Cerra, UIKit Engineer - Apple Inc....•Advanced Animations with UIKit • Session 230 App Frameworks • Basics • Interactive and Interruptible Animations • New Property Animator

•Coordinating Animations

Page 134: Joe Cerra, UIKit Engineer - Apple Inc....•Advanced Animations with UIKit • Session 230 App Frameworks • Basics • Interactive and Interruptible Animations • New Property Animator

Overview

Build a fully interactive, interruptible animated transition

Coordinate across multiple uniquely timed animators

Page 135: Joe Cerra, UIKit Engineer - Apple Inc....•Advanced Animations with UIKit • Session 230 App Frameworks • Basics • Interactive and Interruptible Animations • New Property Animator
Page 136: Joe Cerra, UIKit Engineer - Apple Inc....•Advanced Animations with UIKit • Session 230 App Frameworks • Basics • Interactive and Interruptible Animations • New Property Animator
Page 137: Joe Cerra, UIKit Engineer - Apple Inc....•Advanced Animations with UIKit • Session 230 App Frameworks • Basics • Interactive and Interruptible Animations • New Property Animator
Page 138: Joe Cerra, UIKit Engineer - Apple Inc....•Advanced Animations with UIKit • Session 230 App Frameworks • Basics • Interactive and Interruptible Animations • New Property Animator
Page 139: Joe Cerra, UIKit Engineer - Apple Inc....•Advanced Animations with UIKit • Session 230 App Frameworks • Basics • Interactive and Interruptible Animations • New Property Animator

UITapGestureRecognizer UIPanGestureRecognizer

Page 140: Joe Cerra, UIKit Engineer - Apple Inc....•Advanced Animations with UIKit • Session 230 App Frameworks • Basics • Interactive and Interruptible Animations • New Property Animator

// Tracks all running animators var runningAnimators = [UIViewPropertyAnimator]()

// Perform all animations with animators if not already running func animateTransitionIfNeeded(state: State, duration: TimeInterval) { ... }

// Starts transition if necessary or reverses it on tap func animateOrReverseRunningTransition(state: State, duration: TimeInterval) { ... }

// Starts transition if necessary and pauses on pan .begin func startInteractiveTransition(state: State, duration: TimeInterval) { ... }

// Scrubs transition on pan .changed func updateInteractiveTransition(fractionComplete: CGFloat) { ... }

// Continues or reverse transition on pan .ended func continueInteractiveTransition(cancel: Bool) { ... }

Page 141: Joe Cerra, UIKit Engineer - Apple Inc....•Advanced Animations with UIKit • Session 230 App Frameworks • Basics • Interactive and Interruptible Animations • New Property Animator

// Tracks all running animators var runningAnimators = [UIViewPropertyAnimator]()

// Perform all animations with animators if not already running func animateTransitionIfNeeded(state: State, duration: TimeInterval) { ... }

// Starts transition if necessary or reverses it on tap func animateOrReverseRunningTransition(state: State, duration: TimeInterval) { ... }

// Starts transition if necessary and pauses on pan .begin func startInteractiveTransition(state: State, duration: TimeInterval) { ... }

// Scrubs transition on pan .changed func updateInteractiveTransition(fractionComplete: CGFloat) { ... }

// Continues or reverse transition on pan .ended func continueInteractiveTransition(cancel: Bool) { ... }

Page 142: Joe Cerra, UIKit Engineer - Apple Inc....•Advanced Animations with UIKit • Session 230 App Frameworks • Basics • Interactive and Interruptible Animations • New Property Animator

// Tracks all running animators var runningAnimators = [UIViewPropertyAnimator]()

// Perform all animations with animators if not already running func animateTransitionIfNeeded(state: State, duration: TimeInterval) { ... }

// Starts transition if necessary or reverses it on tap func animateOrReverseRunningTransition(state: State, duration: TimeInterval) { ... }

// Starts transition if necessary and pauses on pan .begin func startInteractiveTransition(state: State, duration: TimeInterval) { ... }

// Scrubs transition on pan .changed func updateInteractiveTransition(fractionComplete: CGFloat) { ... }

// Continues or reverse transition on pan .ended func continueInteractiveTransition(cancel: Bool) { ... }

Page 143: Joe Cerra, UIKit Engineer - Apple Inc....•Advanced Animations with UIKit • Session 230 App Frameworks • Basics • Interactive and Interruptible Animations • New Property Animator

// Perform all animations with animators if not already running func animateTransitionIfNeeded(state: State, duration: TimeInterval) {

Page 144: Joe Cerra, UIKit Engineer - Apple Inc....•Advanced Animations with UIKit • Session 230 App Frameworks • Basics • Interactive and Interruptible Animations • New Property Animator

if runningAnimators.isEmpty { let frameAnimator = UIViewPropertyAnimator(duration: duration, dampingRatio: 1) { switch state { case .Expanded: self.control.frame = CGRect(...) case .Collapsed: self.control.frame = CGRect(...) } } frameAnimator.startAnimation() runningAnimators.append(frameAnimator) } }

// Perform all animations with animators if not already running func animateTransitionIfNeeded(state: State, duration: TimeInterval) {

Page 145: Joe Cerra, UIKit Engineer - Apple Inc....•Advanced Animations with UIKit • Session 230 App Frameworks • Basics • Interactive and Interruptible Animations • New Property Animator

if runningAnimators.isEmpty { let frameAnimator = UIViewPropertyAnimator(duration: duration, dampingRatio: 1) { switch state { case .Expanded: self.control.frame = CGRect(...) case .Collapsed: self.control.frame = CGRect(...) } } frameAnimator.startAnimation() runningAnimators.append(frameAnimator) } }

// Perform all animations with animators if not already running func animateTransitionIfNeeded(state: State, duration: TimeInterval) {

Page 146: Joe Cerra, UIKit Engineer - Apple Inc....•Advanced Animations with UIKit • Session 230 App Frameworks • Basics • Interactive and Interruptible Animations • New Property Animator

if runningAnimators.isEmpty { let frameAnimator = UIViewPropertyAnimator(duration: duration, dampingRatio: 1) { switch state { case .Expanded: self.control.frame = CGRect(...) case .Collapsed: self.control.frame = CGRect(...) } } frameAnimator.startAnimation() runningAnimators.append(frameAnimator) } }

// Perform all animations with animators if not already running func animateTransitionIfNeeded(state: State, duration: TimeInterval) {

Page 147: Joe Cerra, UIKit Engineer - Apple Inc....•Advanced Animations with UIKit • Session 230 App Frameworks • Basics • Interactive and Interruptible Animations • New Property Animator

if runningAnimators.isEmpty { let frameAnimator = UIViewPropertyAnimator(duration: duration, dampingRatio: 1) { switch state { case .Expanded: self.control.frame = CGRect(...) case .Collapsed: self.control.frame = CGRect(...) } } frameAnimator.startAnimation() runningAnimators.append(frameAnimator) } }

// Perform all animations with animators if not already running func animateTransitionIfNeeded(state: State, duration: TimeInterval) {

Page 148: Joe Cerra, UIKit Engineer - Apple Inc....•Advanced Animations with UIKit • Session 230 App Frameworks • Basics • Interactive and Interruptible Animations • New Property Animator

if runningAnimators.isEmpty { let frameAnimator = UIViewPropertyAnimator(duration: duration, dampingRatio: 1) { switch state { case .Expanded: self.control.frame = CGRect(...) case .Collapsed: self.control.frame = CGRect(...) } } frameAnimator.startAnimation() runningAnimators.append(frameAnimator) } }

// Perform all animations with animators if not already running func animateTransitionIfNeeded(state: State, duration: TimeInterval) {

Page 149: Joe Cerra, UIKit Engineer - Apple Inc....•Advanced Animations with UIKit • Session 230 App Frameworks • Basics • Interactive and Interruptible Animations • New Property Animator

// Perform all animations with animators if not already running func animateTransitionIfNeeded(state: State, duration: TimeInterval) {

Page 150: Joe Cerra, UIKit Engineer - Apple Inc....•Advanced Animations with UIKit • Session 230 App Frameworks • Basics • Interactive and Interruptible Animations • New Property Animator

// Perform all animations with animators if not already running func animateTransitionIfNeeded(state: State, duration: TimeInterval) {

Page 151: Joe Cerra, UIKit Engineer - Apple Inc....•Advanced Animations with UIKit • Session 230 App Frameworks • Basics • Interactive and Interruptible Animations • New Property Animator

// Tracks all running animators var runningAnimators = [UIViewPropertyAnimator]()

// Perform all animations with animators if not already running func animateTransitionIfNeeded(state: State, duration: TimeInterval) { ... }

// Starts transition if necessary or reverses it on tap func animateOrReverseRunningTransition(state: State, duration: TimeInterval) { ... }

// Starts transition if necessary and pauses on pan .begin func startInteractiveTransition(state: State, duration: TimeInterval) { ... }

// Scrubs transition on pan .changed func updateInteractiveTransition(fractionComplete: CGFloat) { ... }

// Continues or reverse transition on pan .ended func continueInteractiveTransition(cancel: Bool) { ... }

Page 152: Joe Cerra, UIKit Engineer - Apple Inc....•Advanced Animations with UIKit • Session 230 App Frameworks • Basics • Interactive and Interruptible Animations • New Property Animator

// Tracks all running animators var runningAnimators = [UIViewPropertyAnimator]()

// Perform all animations with animators if not already running func animateTransitionIfNeeded(state: State, duration: TimeInterval) { ... }

// Starts transition if necessary or reverses it on tap func animateOrReverseRunningTransition(state: State, duration: TimeInterval) { ... }

// Starts transition if necessary and pauses on pan .begin func startInteractiveTransition(state: State, duration: TimeInterval) { ... }

// Scrubs transition on pan .changed func updateInteractiveTransition(fractionComplete: CGFloat) { ... }

// Continues or reverse transition on pan .ended func continueInteractiveTransition(cancel: Bool) { ... }

Page 153: Joe Cerra, UIKit Engineer - Apple Inc....•Advanced Animations with UIKit • Session 230 App Frameworks • Basics • Interactive and Interruptible Animations • New Property Animator

// Starts transition if necessary or reverses it on tap func animateOrReverseRunningTransition(state: State, duration: TimeInterval) {

Page 154: Joe Cerra, UIKit Engineer - Apple Inc....•Advanced Animations with UIKit • Session 230 App Frameworks • Basics • Interactive and Interruptible Animations • New Property Animator

if runningAnimators.isEmpty { animateTransitionIfNeeded(state: state, duration: duration) } else { for animator in runningAnimators { animator.isReversed = !animator.isReversed } } }

// Starts transition if necessary or reverses it on tap func animateOrReverseRunningTransition(state: State, duration: TimeInterval) {

Page 155: Joe Cerra, UIKit Engineer - Apple Inc....•Advanced Animations with UIKit • Session 230 App Frameworks • Basics • Interactive and Interruptible Animations • New Property Animator

if runningAnimators.isEmpty { animateTransitionIfNeeded(state: state, duration: duration) } else { for animator in runningAnimators { animator.isReversed = !animator.isReversed } } }

// Starts transition if necessary or reverses it on tap func animateOrReverseRunningTransition(state: State, duration: TimeInterval) {

Page 156: Joe Cerra, UIKit Engineer - Apple Inc....•Advanced Animations with UIKit • Session 230 App Frameworks • Basics • Interactive and Interruptible Animations • New Property Animator

if runningAnimators.isEmpty { animateTransitionIfNeeded(state: state, duration: duration) } else { for animator in runningAnimators { animator.isReversed = !animator.isReversed } } }

// Starts transition if necessary or reverses it on tap func animateOrReverseRunningTransition(state: State, duration: TimeInterval) {

Page 157: Joe Cerra, UIKit Engineer - Apple Inc....•Advanced Animations with UIKit • Session 230 App Frameworks • Basics • Interactive and Interruptible Animations • New Property Animator

// Starts transition if necessary or reverses it on tap func animateOrReverseRunningTransition(state: State, duration: TimeInterval) {

Page 158: Joe Cerra, UIKit Engineer - Apple Inc....•Advanced Animations with UIKit • Session 230 App Frameworks • Basics • Interactive and Interruptible Animations • New Property Animator

// Starts transition if necessary or reverses it on tap func animateOrReverseRunningTransition(state: State, duration: TimeInterval) {

Page 159: Joe Cerra, UIKit Engineer - Apple Inc....•Advanced Animations with UIKit • Session 230 App Frameworks • Basics • Interactive and Interruptible Animations • New Property Animator

// Tracks all running animators var runningAnimators = [UIViewPropertyAnimator]()

// Perform all animations with animators if not already running func animateTransitionIfNeeded(state: State, duration: TimeInterval) { ... }

// Starts transition if necessary or reverses it on tap func animateOrReverseRunningTransition(state: State, duration: TimeInterval) { ... }

// Starts transition if necessary and pauses on pan .begin func startInteractiveTransition(state: State, duration: TimeInterval) { ... }

// Scrubs transition on pan .changed func updateInteractiveTransition(fractionComplete: CGFloat) { ... }

// Continues or reverse transition on pan .ended func continueInteractiveTransition(cancel: Bool) { ... }

Page 160: Joe Cerra, UIKit Engineer - Apple Inc....•Advanced Animations with UIKit • Session 230 App Frameworks • Basics • Interactive and Interruptible Animations • New Property Animator

// Tracks all running animators var runningAnimators = [UIViewPropertyAnimator]()

// Perform all animations with animators if not already running func animateTransitionIfNeeded(state: State, duration: TimeInterval) { ... }

// Starts transition if necessary or reverses it on tap func animateOrReverseRunningTransition(state: State, duration: TimeInterval) { ... }

// Starts transition if necessary and pauses on pan .begin func startInteractiveTransition(state: State, duration: TimeInterval) { ... }

// Scrubs transition on pan .changed func updateInteractiveTransition(fractionComplete: CGFloat) { ... }

// Continues or reverse transition on pan .ended func continueInteractiveTransition(cancel: Bool) { ... }

Page 161: Joe Cerra, UIKit Engineer - Apple Inc....•Advanced Animations with UIKit • Session 230 App Frameworks • Basics • Interactive and Interruptible Animations • New Property Animator

// Tracks all running animators var runningAnimators = [UIViewPropertyAnimator]()

// Perform all animations with animators if not already running func animateTransitionIfNeeded(state: State, duration: TimeInterval) { ... }

// Starts transition if necessary or reverses it on tap func animateOrReverseRunningTransition(state: State, duration: TimeInterval) { ... }

// Starts transition if necessary and pauses on pan .begin func startInteractiveTransition(state: State, duration: TimeInterval) { ... }

// Scrubs transition on pan .changed func updateInteractiveTransition(fractionComplete: CGFloat) { ... }

// Continues or reverse transition on pan .ended func continueInteractiveTransition(cancel: Bool) { ... }

Page 162: Joe Cerra, UIKit Engineer - Apple Inc....•Advanced Animations with UIKit • Session 230 App Frameworks • Basics • Interactive and Interruptible Animations • New Property Animator

// Tracks all running animators var runningAnimators = [UIViewPropertyAnimator]()

// Perform all animations with animators if not already running func animateTransitionIfNeeded(state: State, duration: TimeInterval) { ... }

// Starts transition if necessary or reverses it on tap func animateOrReverseRunningTransition(state: State, duration: TimeInterval) { ... }

// Starts transition if necessary and pauses on pan .begin func startInteractiveTransition(state: State, duration: TimeInterval) { ... }

// Scrubs transition on pan .changed func updateInteractiveTransition(fractionComplete: CGFloat) { ... }

// Continues or reverse transition on pan .ended func continueInteractiveTransition(cancel: Bool) { ... }

Page 163: Joe Cerra, UIKit Engineer - Apple Inc....•Advanced Animations with UIKit • Session 230 App Frameworks • Basics • Interactive and Interruptible Animations • New Property Animator
Page 164: Joe Cerra, UIKit Engineer - Apple Inc....•Advanced Animations with UIKit • Session 230 App Frameworks • Basics • Interactive and Interruptible Animations • New Property Animator
Page 165: Joe Cerra, UIKit Engineer - Apple Inc....•Advanced Animations with UIKit • Session 230 App Frameworks • Basics • Interactive and Interruptible Animations • New Property Animator
Page 166: Joe Cerra, UIKit Engineer - Apple Inc....•Advanced Animations with UIKit • Session 230 App Frameworks • Basics • Interactive and Interruptible Animations • New Property Animator
Page 167: Joe Cerra, UIKit Engineer - Apple Inc....•Advanced Animations with UIKit • Session 230 App Frameworks • Basics • Interactive and Interruptible Animations • New Property Animator
Page 168: Joe Cerra, UIKit Engineer - Apple Inc....•Advanced Animations with UIKit • Session 230 App Frameworks • Basics • Interactive and Interruptible Animations • New Property Animator
Page 169: Joe Cerra, UIKit Engineer - Apple Inc....•Advanced Animations with UIKit • Session 230 App Frameworks • Basics • Interactive and Interruptible Animations • New Property Animator
Page 170: Joe Cerra, UIKit Engineer - Apple Inc....•Advanced Animations with UIKit • Session 230 App Frameworks • Basics • Interactive and Interruptible Animations • New Property Animator
Page 171: Joe Cerra, UIKit Engineer - Apple Inc....•Advanced Animations with UIKit • Session 230 App Frameworks • Basics • Interactive and Interruptible Animations • New Property Animator
Page 172: Joe Cerra, UIKit Engineer - Apple Inc....•Advanced Animations with UIKit • Session 230 App Frameworks • Basics • Interactive and Interruptible Animations • New Property Animator
Page 173: Joe Cerra, UIKit Engineer - Apple Inc....•Advanced Animations with UIKit • Session 230 App Frameworks • Basics • Interactive and Interruptible Animations • New Property Animator

Animating a Blur

Page 174: Joe Cerra, UIKit Engineer - Apple Inc....•Advanced Animations with UIKit • Session 230 App Frameworks • Basics • Interactive and Interruptible Animations • New Property Animator

UIVisualEffectView

class UIVisualEffectView: UIView {

var effect: UIVisualEffect // animatable

}

class UIBlurEffect: UIVisualEffect { init(style: UIBlurEffectStyle) }

class UIVibrancyEffect: UIVisualEffect { init(blurEffect: UIBlurEffect) }

Page 175: Joe Cerra, UIKit Engineer - Apple Inc....•Advanced Animations with UIKit • Session 230 App Frameworks • Basics • Interactive and Interruptible Animations • New Property Animator

func animateTransitionIfNeeded(forState state: State, duration: TimeInterval) { // ... let blurAnimator = UIViewPropertyAnimator(duration: duration, dampingRatio: 1) { switch state { case .Expanded: self.blurEffectView.effect = UIBlurEffect(style: .dark) } case .Collapsed: self.blurEffectView.effect = nil } } blurAnimator.startAnimation() runningAnimators.append(blurAnimator) // ... }

Page 176: Joe Cerra, UIKit Engineer - Apple Inc....•Advanced Animations with UIKit • Session 230 App Frameworks • Basics • Interactive and Interruptible Animations • New Property Animator

func animateTransitionIfNeeded(forState state: State, duration: TimeInterval) { // ... let blurAnimator = UIViewPropertyAnimator(duration: duration, dampingRatio: 1) { switch state { case .Expanded: self.blurEffectView.effect = UIBlurEffect(style: .dark) } case .Collapsed: self.blurEffectView.effect = nil } } blurAnimator.startAnimation() runningAnimators.append(blurAnimator) // ... }

Page 177: Joe Cerra, UIKit Engineer - Apple Inc....•Advanced Animations with UIKit • Session 230 App Frameworks • Basics • Interactive and Interruptible Animations • New Property Animator

func animateTransitionIfNeeded(forState state: State, duration: TimeInterval) { // ... let blurAnimator = UIViewPropertyAnimator(duration: duration, dampingRatio: 1) { switch state { case .Expanded: self.blurEffectView.effect = UIBlurEffect(style: .dark) } case .Collapsed: self.blurEffectView.effect = nil } } blurAnimator.startAnimation() runningAnimators.append(blurAnimator) // ... }

Page 178: Joe Cerra, UIKit Engineer - Apple Inc....•Advanced Animations with UIKit • Session 230 App Frameworks • Basics • Interactive and Interruptible Animations • New Property Animator

func animateTransitionIfNeeded(forState state: State, duration: TimeInterval) { // ... let blurAnimator = UIViewPropertyAnimator(duration: duration, dampingRatio: 1) { switch state { case .Expanded: self.blurEffectView.effect = UIBlurEffect(style: .dark) } case .Collapsed: self.blurEffectView.effect = nil } } blurAnimator.startAnimation() runningAnimators.append(blurAnimator) // ... }

Page 179: Joe Cerra, UIKit Engineer - Apple Inc....•Advanced Animations with UIKit • Session 230 App Frameworks • Basics • Interactive and Interruptible Animations • New Property Animator
Page 180: Joe Cerra, UIKit Engineer - Apple Inc....•Advanced Animations with UIKit • Session 230 App Frameworks • Basics • Interactive and Interruptible Animations • New Property Animator
Page 181: Joe Cerra, UIKit Engineer - Apple Inc....•Advanced Animations with UIKit • Session 230 App Frameworks • Basics • Interactive and Interruptible Animations • New Property Animator
Page 182: Joe Cerra, UIKit Engineer - Apple Inc....•Advanced Animations with UIKit • Session 230 App Frameworks • Basics • Interactive and Interruptible Animations • New Property Animator
Page 183: Joe Cerra, UIKit Engineer - Apple Inc....•Advanced Animations with UIKit • Session 230 App Frameworks • Basics • Interactive and Interruptible Animations • New Property Animator
Page 184: Joe Cerra, UIKit Engineer - Apple Inc....•Advanced Animations with UIKit • Session 230 App Frameworks • Basics • Interactive and Interruptible Animations • New Property Animator
Page 185: Joe Cerra, UIKit Engineer - Apple Inc....•Advanced Animations with UIKit • Session 230 App Frameworks • Basics • Interactive and Interruptible Animations • New Property Animator
Page 186: Joe Cerra, UIKit Engineer - Apple Inc....•Advanced Animations with UIKit • Session 230 App Frameworks • Basics • Interactive and Interruptible Animations • New Property Animator
Page 187: Joe Cerra, UIKit Engineer - Apple Inc....•Advanced Animations with UIKit • Session 230 App Frameworks • Basics • Interactive and Interruptible Animations • New Property Animator

Issues

Page 188: Joe Cerra, UIKit Engineer - Apple Inc....•Advanced Animations with UIKit • Session 230 App Frameworks • Basics • Interactive and Interruptible Animations • New Property Animator

Issues

Too fast animating in

1.0

0.0 1.0

0.5

Progress

0.5 Time

Page 189: Joe Cerra, UIKit Engineer - Apple Inc....•Advanced Animations with UIKit • Session 230 App Frameworks • Basics • Interactive and Interruptible Animations • New Property Animator

Issues

Still too fast animating in / out

1.0

0.0 1.0

0.5

Progress

0.5 Time

Page 190: Joe Cerra, UIKit Engineer - Apple Inc....•Advanced Animations with UIKit • Session 230 App Frameworks • Basics • Interactive and Interruptible Animations • New Property Animator

Custom Timing Symmetric pacing

Custom Ease In

Animates our blur in slowly (0.75, 0.1) (0.9, 0.25)

1.0

0.0 1.0

0.5

Progress

0.5

Custom Ease Out

Animates our blur out quickly (0.1, 0.75) (0.25, 0.9)

1.0

0.0 1.0

0.5

0.5 Time

Page 191: Joe Cerra, UIKit Engineer - Apple Inc....•Advanced Animations with UIKit • Session 230 App Frameworks • Basics • Interactive and Interruptible Animations • New Property Animator

func animateTransitionIfNeeded(forState state: State, duration: TimeInterval) { // ... let timing: UITimingCurveProvider switch state { case .Expanded: timing = UICubicTimingParameters(controlPoint1: CGPoint(x: 0.75, y: 0.1), controlPoint2: CGPoint(x: 0.9, y: 0.25)) case .Collapsed: timing = UICubicTimingParameters(controlPoint1: CGPoint(x: 0.1, y: 0.75), controlPoint2: CGPoint(x: 0.25, y: 0.9)) } let blurAnimator = UIViewPropertyAnimator(duration: duration, timingParameters: timing) blurAnimator.scrubsLinearly = false // ... }

Page 192: Joe Cerra, UIKit Engineer - Apple Inc....•Advanced Animations with UIKit • Session 230 App Frameworks • Basics • Interactive and Interruptible Animations • New Property Animator
Page 193: Joe Cerra, UIKit Engineer - Apple Inc....•Advanced Animations with UIKit • Session 230 App Frameworks • Basics • Interactive and Interruptible Animations • New Property Animator
Page 194: Joe Cerra, UIKit Engineer - Apple Inc....•Advanced Animations with UIKit • Session 230 App Frameworks • Basics • Interactive and Interruptible Animations • New Property Animator
Page 195: Joe Cerra, UIKit Engineer - Apple Inc....•Advanced Animations with UIKit • Session 230 App Frameworks • Basics • Interactive and Interruptible Animations • New Property Animator
Page 196: Joe Cerra, UIKit Engineer - Apple Inc....•Advanced Animations with UIKit • Session 230 App Frameworks • Basics • Interactive and Interruptible Animations • New Property Animator
Page 197: Joe Cerra, UIKit Engineer - Apple Inc....•Advanced Animations with UIKit • Session 230 App Frameworks • Basics • Interactive and Interruptible Animations • New Property Animator
Page 198: Joe Cerra, UIKit Engineer - Apple Inc....•Advanced Animations with UIKit • Session 230 App Frameworks • Basics • Interactive and Interruptible Animations • New Property Animator
Page 199: Joe Cerra, UIKit Engineer - Apple Inc....•Advanced Animations with UIKit • Session 230 App Frameworks • Basics • Interactive and Interruptible Animations • New Property Animator
Page 200: Joe Cerra, UIKit Engineer - Apple Inc....•Advanced Animations with UIKit • Session 230 App Frameworks • Basics • Interactive and Interruptible Animations • New Property Animator

View Morphing

Hello

Page 201: Joe Cerra, UIKit Engineer - Apple Inc....•Advanced Animations with UIKit • Session 230 App Frameworks • Basics • Interactive and Interruptible Animations • New Property Animator

View Morphing

Hello

Page 202: Joe Cerra, UIKit Engineer - Apple Inc....•Advanced Animations with UIKit • Session 230 App Frameworks • Basics • Interactive and Interruptible Animations • New Property Animator

View Morphing

Scaling, translation, and opacity blending of two views

Page 203: Joe Cerra, UIKit Engineer - Apple Inc....•Advanced Animations with UIKit • Session 230 App Frameworks • Basics • Interactive and Interruptible Animations • New Property Animator

159

Page 204: Joe Cerra, UIKit Engineer - Apple Inc....•Advanced Animations with UIKit • Session 230 App Frameworks • Basics • Interactive and Interruptible Animations • New Property Animator

160

Page 205: Joe Cerra, UIKit Engineer - Apple Inc....•Advanced Animations with UIKit • Session 230 App Frameworks • Basics • Interactive and Interruptible Animations • New Property Animator

161

Page 206: Joe Cerra, UIKit Engineer - Apple Inc....•Advanced Animations with UIKit • Session 230 App Frameworks • Basics • Interactive and Interruptible Animations • New Property Animator

161

Page 207: Joe Cerra, UIKit Engineer - Apple Inc....•Advanced Animations with UIKit • Session 230 App Frameworks • Basics • Interactive and Interruptible Animations • New Property Animator

Strategy

Page 208: Joe Cerra, UIKit Engineer - Apple Inc....•Advanced Animations with UIKit • Session 230 App Frameworks • Basics • Interactive and Interruptible Animations • New Property Animator

Strategy

.transform: CGAffineTransform

Compute transform.scale and transform.translation

Prepare views and animate .transform and .alpha

Page 209: Joe Cerra, UIKit Engineer - Apple Inc....•Advanced Animations with UIKit • Session 230 App Frameworks • Basics • Interactive and Interruptible Animations • New Property Animator

Computing Scale

Hello

w

h HelloW

H

Page 210: Joe Cerra, UIKit Engineer - Apple Inc....•Advanced Animations with UIKit • Session 230 App Frameworks • Basics • Interactive and Interruptible Animations • New Property Animator

Computing Scale

Hello

w

h HelloW

H

.scale.width = Ww

.scale.height = Hh

.scale.width = wW

.scale.height = hH

Page 211: Joe Cerra, UIKit Engineer - Apple Inc....•Advanced Animations with UIKit • Session 230 App Frameworks • Basics • Interactive and Interruptible Animations • New Property Animator

Computing Scale

Hello

w

h HelloW

H

.scale.width = Ww

.scale.height = Hh

.scale.width = wW

.scale.height = hH

= .scale.width

1

= .scale.height

1

Page 212: Joe Cerra, UIKit Engineer - Apple Inc....•Advanced Animations with UIKit • Session 230 App Frameworks • Basics • Interactive and Interruptible Animations • New Property Animator

Computing Translation

Hello

HelloY

y’

Page 213: Joe Cerra, UIKit Engineer - Apple Inc....•Advanced Animations with UIKit • Session 230 App Frameworks • Basics • Interactive and Interruptible Animations • New Property Animator

Hello

Computing Translation

Hellotranslation.y = Y - y’

y’

Y

Page 214: Joe Cerra, UIKit Engineer - Apple Inc....•Advanced Animations with UIKit • Session 230 App Frameworks • Basics • Interactive and Interruptible Animations • New Property Animator

Animations

1.0

0.0 1.0

0.5

Progress

0.5

.transform

Critically Damped Spring

1.0

0.0 1.0

0.5

0.5

Incoming view .alpha Non linear scrubbing

.easeIn

1.0

0.0 1.0

0.5

0.5

Outgoing view .alpha Non linear scrubbing

.easeOut

Time

Page 215: Joe Cerra, UIKit Engineer - Apple Inc....•Advanced Animations with UIKit • Session 230 App Frameworks • Basics • Interactive and Interruptible Animations • New Property Animator

func animateTransitionIfNeeded(forState state: State, duration: TimeInterval) { // ... let transformAnimator = UIViewPropertyAnimator(duration: duration, dampingRatio: 1) { inLabel.transform = CGAffineTransform.identity outLabel.transform = inLabelScale.concatenating(inLabelTranslation) } // ... let inLabelAnimator = UIViewPropertyAnimator(duration: duration, curve: .easeIn) { inLabel.alpha = 1 } inLabelAnimator.scrubsLinearly = false // ... let outLabelAnimator = UIViewPropertyAnimator(duration: duration, curve: .easeOut) { outLabel.alpha = 0 } outLabelAnimator.scrubsLinearly = false // ... }

Page 216: Joe Cerra, UIKit Engineer - Apple Inc....•Advanced Animations with UIKit • Session 230 App Frameworks • Basics • Interactive and Interruptible Animations • New Property Animator

func animateTransitionIfNeeded(forState state: State, duration: TimeInterval) { // ... let transformAnimator = UIViewPropertyAnimator(duration: duration, dampingRatio: 1) { inLabel.transform = CGAffineTransform.identity outLabel.transform = inLabelScale.concatenating(inLabelTranslation) } // ... let inLabelAnimator = UIViewPropertyAnimator(duration: duration, curve: .easeIn) { inLabel.alpha = 1 } inLabelAnimator.scrubsLinearly = false // ... let outLabelAnimator = UIViewPropertyAnimator(duration: duration, curve: .easeOut) { outLabel.alpha = 0 } outLabelAnimator.scrubsLinearly = false // ... }

Page 217: Joe Cerra, UIKit Engineer - Apple Inc....•Advanced Animations with UIKit • Session 230 App Frameworks • Basics • Interactive and Interruptible Animations • New Property Animator

func animateTransitionIfNeeded(forState state: State, duration: TimeInterval) { // ... let transformAnimator = UIViewPropertyAnimator(duration: duration, dampingRatio: 1) { inLabel.transform = CGAffineTransform.identity outLabel.transform = inLabelScale.concatenating(inLabelTranslation) } // ... let inLabelAnimator = UIViewPropertyAnimator(duration: duration, curve: .easeIn) { inLabel.alpha = 1 } inLabelAnimator.scrubsLinearly = false // ... let outLabelAnimator = UIViewPropertyAnimator(duration: duration, curve: .easeOut) { outLabel.alpha = 0 } outLabelAnimator.scrubsLinearly = false // ... }

Page 218: Joe Cerra, UIKit Engineer - Apple Inc....•Advanced Animations with UIKit • Session 230 App Frameworks • Basics • Interactive and Interruptible Animations • New Property Animator

func animateTransitionIfNeeded(forState state: State, duration: TimeInterval) { // ... let transformAnimator = UIViewPropertyAnimator(duration: duration, dampingRatio: 1) { inLabel.transform = CGAffineTransform.identity outLabel.transform = inLabelScale.concatenating(inLabelTranslation) } // ... let inLabelAnimator = UIViewPropertyAnimator(duration: duration, curve: .easeIn) { inLabel.alpha = 1 } inLabelAnimator.scrubsLinearly = false // ... let outLabelAnimator = UIViewPropertyAnimator(duration: duration, curve: .easeOut) { outLabel.alpha = 0 } outLabelAnimator.scrubsLinearly = false // ... }

Page 219: Joe Cerra, UIKit Engineer - Apple Inc....•Advanced Animations with UIKit • Session 230 App Frameworks • Basics • Interactive and Interruptible Animations • New Property Animator
Page 220: Joe Cerra, UIKit Engineer - Apple Inc....•Advanced Animations with UIKit • Session 230 App Frameworks • Basics • Interactive and Interruptible Animations • New Property Animator
Page 221: Joe Cerra, UIKit Engineer - Apple Inc....•Advanced Animations with UIKit • Session 230 App Frameworks • Basics • Interactive and Interruptible Animations • New Property Animator

175

Page 222: Joe Cerra, UIKit Engineer - Apple Inc....•Advanced Animations with UIKit • Session 230 App Frameworks • Basics • Interactive and Interruptible Animations • New Property Animator

175

Page 223: Joe Cerra, UIKit Engineer - Apple Inc....•Advanced Animations with UIKit • Session 230 App Frameworks • Basics • Interactive and Interruptible Animations • New Property Animator
Page 224: Joe Cerra, UIKit Engineer - Apple Inc....•Advanced Animations with UIKit • Session 230 App Frameworks • Basics • Interactive and Interruptible Animations • New Property Animator
Page 225: Joe Cerra, UIKit Engineer - Apple Inc....•Advanced Animations with UIKit • Session 230 App Frameworks • Basics • Interactive and Interruptible Animations • New Property Animator
Page 226: Joe Cerra, UIKit Engineer - Apple Inc....•Advanced Animations with UIKit • Session 230 App Frameworks • Basics • Interactive and Interruptible Animations • New Property Animator
Page 227: Joe Cerra, UIKit Engineer - Apple Inc....•Advanced Animations with UIKit • Session 230 App Frameworks • Basics • Interactive and Interruptible Animations • New Property Animator

1.0

0.0 1.0

0.5

Progre

0.5

Comments View

1.0

0.0 1.0

0.5

Progre

0.5

Label Transform

1.0

0.0 1.0

0.5

0.5

Label Alpha In

1.0

0.0 1.0

0.5

0.5

Label Alpha Out

Time

1.0

0.0 1.0

0.5

0.5

Blur In

1.0

0.0 1.0

0.5

0.5

Blur Out

Time

Page 228: Joe Cerra, UIKit Engineer - Apple Inc....•Advanced Animations with UIKit • Session 230 App Frameworks • Basics • Interactive and Interruptible Animations • New Property Animator

•Tips and Tricks

Page 229: Joe Cerra, UIKit Engineer - Apple Inc....•Advanced Animations with UIKit • Session 230 App Frameworks • Basics • Interactive and Interruptible Animations • New Property Animator

Animating Corner Radius

Page 230: Joe Cerra, UIKit Engineer - Apple Inc....•Advanced Animations with UIKit • Session 230 App Frameworks • Basics • Interactive and Interruptible Animations • New Property Animator
Page 231: Joe Cerra, UIKit Engineer - Apple Inc....•Advanced Animations with UIKit • Session 230 App Frameworks • Basics • Interactive and Interruptible Animations • New Property Animator

.cornerRadius Now animatable in UIKit

CALayer var .cornerRadius: CGFloat

NEW

Page 232: Joe Cerra, UIKit Engineer - Apple Inc....•Advanced Animations with UIKit • Session 230 App Frameworks • Basics • Interactive and Interruptible Animations • New Property Animator

.cornerRadius Now animatable in UIKit

CALayer var .cornerRadius: CGFloat

circle.clipsToBounds = true UIViewPropertyAnimator(duration: 1, curve: .linear) { circle.layer.cornerRadius = 12 }.startAnimation()

NEW

Page 233: Joe Cerra, UIKit Engineer - Apple Inc....•Advanced Animations with UIKit • Session 230 App Frameworks • Basics • Interactive and Interruptible Animations • New Property Animator
Page 234: Joe Cerra, UIKit Engineer - Apple Inc....•Advanced Animations with UIKit • Session 230 App Frameworks • Basics • Interactive and Interruptible Animations • New Property Animator
Page 235: Joe Cerra, UIKit Engineer - Apple Inc....•Advanced Animations with UIKit • Session 230 App Frameworks • Basics • Interactive and Interruptible Animations • New Property Animator

.maskedCorners New in iOS 11

CALayer var .maskedCorners: CACornerMask

NEW

Page 236: Joe Cerra, UIKit Engineer - Apple Inc....•Advanced Animations with UIKit • Session 230 App Frameworks • Basics • Interactive and Interruptible Animations • New Property Animator

.maskedCorners New in iOS 11

CALayer var .maskedCorners: CACornerMask

NEW

Page 237: Joe Cerra, UIKit Engineer - Apple Inc....•Advanced Animations with UIKit • Session 230 App Frameworks • Basics • Interactive and Interruptible Animations • New Property Animator

.maskedCorners New in iOS 11

CALayer var .maskedCorners: CACornerMask

circle.layer.maskedCorners = [.layerMinXMinYCorner, .layerMaxXMinYCorner]

NEW

Page 238: Joe Cerra, UIKit Engineer - Apple Inc....•Advanced Animations with UIKit • Session 230 App Frameworks • Basics • Interactive and Interruptible Animations • New Property Animator

func animateTransitionIfNeeded(forState state: State, duration: TimeInterval) { // ... let cornerAnimator = UIViewPropertyAnimator(duration: duration, curve: .linear) { switch state { case .Expanded: self.control.layer.cornerRadius = 12 case .Collapsed: self.control.layer.cornerRadius = 0 } } // ... }

Page 239: Joe Cerra, UIKit Engineer - Apple Inc....•Advanced Animations with UIKit • Session 230 App Frameworks • Basics • Interactive and Interruptible Animations • New Property Animator
Page 240: Joe Cerra, UIKit Engineer - Apple Inc....•Advanced Animations with UIKit • Session 230 App Frameworks • Basics • Interactive and Interruptible Animations • New Property Animator
Page 241: Joe Cerra, UIKit Engineer - Apple Inc....•Advanced Animations with UIKit • Session 230 App Frameworks • Basics • Interactive and Interruptible Animations • New Property Animator
Page 242: Joe Cerra, UIKit Engineer - Apple Inc....•Advanced Animations with UIKit • Session 230 App Frameworks • Basics • Interactive and Interruptible Animations • New Property Animator
Page 243: Joe Cerra, UIKit Engineer - Apple Inc....•Advanced Animations with UIKit • Session 230 App Frameworks • Basics • Interactive and Interruptible Animations • New Property Animator

Component Timing

1.0

0.0 1.0

0.5

Progress

0.5 Time

Page 244: Joe Cerra, UIKit Engineer - Apple Inc....•Advanced Animations with UIKit • Session 230 App Frameworks • Basics • Interactive and Interruptible Animations • New Property Animator

Component Timing

1.0

0.0 1.0

0.5

Progress

0.5 Time

Page 245: Joe Cerra, UIKit Engineer - Apple Inc....•Advanced Animations with UIKit • Session 230 App Frameworks • Basics • Interactive and Interruptible Animations • New Property Animator

Component Timing

1.0

0.0 1.0

0.5

Progress

0.5 Time

Page 246: Joe Cerra, UIKit Engineer - Apple Inc....•Advanced Animations with UIKit • Session 230 App Frameworks • Basics • Interactive and Interruptible Animations • New Property Animator

Component Timing

1.0

0.0 1.0

0.5

Progress

0.5 Time

Page 247: Joe Cerra, UIKit Engineer - Apple Inc....•Advanced Animations with UIKit • Session 230 App Frameworks • Basics • Interactive and Interruptible Animations • New Property Animator

Component Timing

1.0

0.0 1.0

0.5

Progress

0.5 Time

Page 248: Joe Cerra, UIKit Engineer - Apple Inc....•Advanced Animations with UIKit • Session 230 App Frameworks • Basics • Interactive and Interruptible Animations • New Property Animator
Page 249: Joe Cerra, UIKit Engineer - Apple Inc....•Advanced Animations with UIKit • Session 230 App Frameworks • Basics • Interactive and Interruptible Animations • New Property Animator
Page 250: Joe Cerra, UIKit Engineer - Apple Inc....•Advanced Animations with UIKit • Session 230 App Frameworks • Basics • Interactive and Interruptible Animations • New Property Animator
Page 251: Joe Cerra, UIKit Engineer - Apple Inc....•Advanced Animations with UIKit • Session 230 App Frameworks • Basics • Interactive and Interruptible Animations • New Property Animator
Page 252: Joe Cerra, UIKit Engineer - Apple Inc....•Advanced Animations with UIKit • Session 230 App Frameworks • Basics • Interactive and Interruptible Animations • New Property Animator
Page 253: Joe Cerra, UIKit Engineer - Apple Inc....•Advanced Animations with UIKit • Session 230 App Frameworks • Basics • Interactive and Interruptible Animations • New Property Animator
Page 254: Joe Cerra, UIKit Engineer - Apple Inc....•Advanced Animations with UIKit • Session 230 App Frameworks • Basics • Interactive and Interruptible Animations • New Property Animator

Keyframe Animations

Page 255: Joe Cerra, UIKit Engineer - Apple Inc....•Advanced Animations with UIKit • Session 230 App Frameworks • Basics • Interactive and Interruptible Animations • New Property Animator

UIView

func animateKeyframes(withDuration duration: TimeInterval, delay: TimeInterval, options: ..., animations: ..., completion: …)

func addKeyframe(withRelativeStartTime frameStartTime: Double, relativeDuration frameDuration: Double, animations: ...)

Keyframe Animations

Page 256: Joe Cerra, UIKit Engineer - Apple Inc....•Advanced Animations with UIKit • Session 230 App Frameworks • Basics • Interactive and Interruptible Animations • New Property Animator

Keyframe Animations

UIView

func animateKeyframes(withDuration duration: TimeInterval, delay: TimeInterval, options: ..., animations: ..., completion: …)

func addKeyframe(withRelativeStartTime frameStartTime: Double, relativeDuration frameDuration: Double, animations: ...)

Page 257: Joe Cerra, UIKit Engineer - Apple Inc....•Advanced Animations with UIKit • Session 230 App Frameworks • Basics • Interactive and Interruptible Animations • New Property Animator

func animateTransitionIfNeeded(forState state: State, duration: TimeInterval) { // ... let buttonAnimator = UIViewPropertyAnimator(duration: duration, curve: .linear) { UIView.animateKeyframes(withDuration: 0.0, delay: 0.0, options: [], animations: { switch state { case .Expanded: UIView.addKeyframe(withRelativeStartTime: 0.5, relativeDuration: 0.5) { // Start with delay and finish with rest of animations detailsButton.alpha = 1 }) case .Collapsed: UIView.addKeyframe(withRelativeStartTime: 0.0, relativeDuration: 0.5) { // Start immediately and finish in half the time detailsButton.alpha = 0 }) } }, completion: nil) } }

Page 258: Joe Cerra, UIKit Engineer - Apple Inc....•Advanced Animations with UIKit • Session 230 App Frameworks • Basics • Interactive and Interruptible Animations • New Property Animator

func animateTransitionIfNeeded(forState state: State, duration: TimeInterval) { // ... let buttonAnimator = UIViewPropertyAnimator(duration: duration, curve: .linear) { UIView.animateKeyframes(withDuration: 0.0, delay: 0.0, options: [], animations: { switch state { case .Expanded: UIView.addKeyframe(withRelativeStartTime: 0.5, relativeDuration: 0.5) { // Start with delay and finish with rest of animations detailsButton.alpha = 1 }) case .Collapsed: UIView.addKeyframe(withRelativeStartTime: 0.0, relativeDuration: 0.5) { // Start immediately and finish in half the time detailsButton.alpha = 0 }) } }, completion: nil) } }

Page 259: Joe Cerra, UIKit Engineer - Apple Inc....•Advanced Animations with UIKit • Session 230 App Frameworks • Basics • Interactive and Interruptible Animations • New Property Animator

func animateTransitionIfNeeded(forState state: State, duration: TimeInterval) { // ... let buttonAnimator = UIViewPropertyAnimator(duration: duration, curve: .linear) { UIView.animateKeyframes(withDuration: 0.0, delay: 0.0, options: [], animations: { switch state { case .Expanded: UIView.addKeyframe(withRelativeStartTime: 0.5, relativeDuration: 0.5) { // Start with delay and finish with rest of animations detailsButton.alpha = 1 }) case .Collapsed: UIView.addKeyframe(withRelativeStartTime: 0.0, relativeDuration: 0.5) { // Start immediately and finish in half the time detailsButton.alpha = 0 }) } }, completion: nil) } }

Page 260: Joe Cerra, UIKit Engineer - Apple Inc....•Advanced Animations with UIKit • Session 230 App Frameworks • Basics • Interactive and Interruptible Animations • New Property Animator

func animateTransitionIfNeeded(forState state: State, duration: TimeInterval) { // ... let buttonAnimator = UIViewPropertyAnimator(duration: duration, curve: .linear) { UIView.animateKeyframes(withDuration: 0.0, delay: 0.0, options: [], animations: { switch state { case .Expanded: UIView.addKeyframe(withRelativeStartTime: 0.5, relativeDuration: 0.5) { // Start with delay and finish with rest of animations detailsButton.alpha = 1 }) case .Collapsed: UIView.addKeyframe(withRelativeStartTime: 0.0, relativeDuration: 0.5) { // Start immediately and finish in half the time detailsButton.alpha = 0 }) } }, completion: nil) } }

Page 261: Joe Cerra, UIKit Engineer - Apple Inc....•Advanced Animations with UIKit • Session 230 App Frameworks • Basics • Interactive and Interruptible Animations • New Property Animator

func animateTransitionIfNeeded(forState state: State, duration: TimeInterval) { // ... let buttonAnimator = UIViewPropertyAnimator(duration: duration, curve: .linear) { UIView.animateKeyframes(withDuration: 0.0, delay: 0.0, options: [], animations: { switch state { case .Expanded: UIView.addKeyframe(withRelativeStartTime: 0.5, relativeDuration: 0.5) { // Start with delay and finish with rest of animations detailsButton.alpha = 1 }) case .Collapsed: UIView.addKeyframe(withRelativeStartTime: 0.0, relativeDuration: 0.5) { // Start immediately and finish in half the time detailsButton.alpha = 0 }) } }, completion: nil) } }

Page 262: Joe Cerra, UIKit Engineer - Apple Inc....•Advanced Animations with UIKit • Session 230 App Frameworks • Basics • Interactive and Interruptible Animations • New Property Animator

Additive Animations

Page 263: Joe Cerra, UIKit Engineer - Apple Inc....•Advanced Animations with UIKit • Session 230 App Frameworks • Basics • Interactive and Interruptible Animations • New Property Animator

Additive Animations

Page 264: Joe Cerra, UIKit Engineer - Apple Inc....•Advanced Animations with UIKit • Session 230 App Frameworks • Basics • Interactive and Interruptible Animations • New Property Animator

Additive Animations

Page 265: Joe Cerra, UIKit Engineer - Apple Inc....•Advanced Animations with UIKit • Session 230 App Frameworks • Basics • Interactive and Interruptible Animations • New Property Animator

Additive Animations

let animator = UIViewPropertyAnimator(duration: 5, curve: .easeInOut) { square.transform = CGAffineTransform(rotationAngle: CGFloat(Double.pi * 20)) } animator.startAnimation()

Page 266: Joe Cerra, UIKit Engineer - Apple Inc....•Advanced Animations with UIKit • Session 230 App Frameworks • Basics • Interactive and Interruptible Animations • New Property Animator

CGAffineTransform(rotationAngle: CGFloat(Double.pi * 20))

Page 267: Joe Cerra, UIKit Engineer - Apple Inc....•Advanced Animations with UIKit • Session 230 App Frameworks • Basics • Interactive and Interruptible Animations • New Property Animator

CGAffineTransform(rotationAngle: CGFloat(-Double.pi))

Page 268: Joe Cerra, UIKit Engineer - Apple Inc....•Advanced Animations with UIKit • Session 230 App Frameworks • Basics • Interactive and Interruptible Animations • New Property Animator

CGAffineTransform(rotationAngle: CGFloat(-Double.pi))

180°

Page 269: Joe Cerra, UIKit Engineer - Apple Inc....•Advanced Animations with UIKit • Session 230 App Frameworks • Basics • Interactive and Interruptible Animations • New Property Animator

CGAffineTransform(rotationAngle: CGFloat(-Double.pi))

Page 270: Joe Cerra, UIKit Engineer - Apple Inc....•Advanced Animations with UIKit • Session 230 App Frameworks • Basics • Interactive and Interruptible Animations • New Property Animator

CGAffineTransform(rotationAngle: CGFloat(-Double.pi))

+180°

Page 271: Joe Cerra, UIKit Engineer - Apple Inc....•Advanced Animations with UIKit • Session 230 App Frameworks • Basics • Interactive and Interruptible Animations • New Property Animator

Options

Use Core Animation • Low level • No scrubbing

Page 272: Joe Cerra, UIKit Engineer - Apple Inc....•Advanced Animations with UIKit • Session 230 App Frameworks • Basics • Interactive and Interruptible Animations • New Property Animator

Options

Use Core Animation • Low level • No scrubbing

Decompose into several smaller additive rotation animations

Page 273: Joe Cerra, UIKit Engineer - Apple Inc....•Advanced Animations with UIKit • Session 230 App Frameworks • Basics • Interactive and Interruptible Animations • New Property Animator

Additively Animatable Properties

var transform: CGAffineTransform // affine only

var frame: CGRect

var bounds: CGRect var center: CGPoint

var position: CGPoint

Page 274: Joe Cerra, UIKit Engineer - Apple Inc....•Advanced Animations with UIKit • Session 230 App Frameworks • Basics • Interactive and Interruptible Animations • New Property Animator

Decomposed Additive Animations

let animator = UIViewPropertyAnimator(duration: 5, curve: .easeInOut, animations: { for _ in 0..<20 { let rotation = CGAffineTransform(rotationAngle: CGFloat(Double.pi)) square.transform = square.transform.concatenating(rotation) } }) animator.startAnimation()

Page 275: Joe Cerra, UIKit Engineer - Apple Inc....•Advanced Animations with UIKit • Session 230 App Frameworks • Basics • Interactive and Interruptible Animations • New Property Animator

Decomposed Additive Animations

let animator = UIViewPropertyAnimator(duration: 5, curve: .easeInOut, animations: { for _ in 0..<20 { let rotation = CGAffineTransform(rotationAngle: CGFloat(Double.pi)) square.transform = square.transform.concatenating(rotation) } }) animator.startAnimation()

Page 276: Joe Cerra, UIKit Engineer - Apple Inc....•Advanced Animations with UIKit • Session 230 App Frameworks • Basics • Interactive and Interruptible Animations • New Property Animator

Summary

Modern methods for making animations interactive and interruptible

Coordinating several animations during interactive transition

Page 277: Joe Cerra, UIKit Engineer - Apple Inc....•Advanced Animations with UIKit • Session 230 App Frameworks • Basics • Interactive and Interruptible Animations • New Property Animator

Related Sessions

What's New in Cocoa Touch Hall 3 Tuesday 10:20AM

Introducing Drag and Drop Hall 3 Tuesday 11:20AM

Mastering Drag and Drop Executive Ballroom Wednesday 11:00AM

Modern User Interaction on iOS Grand Ballroom B Wednesday 4:10PM

Drag and Drop with Collection and Table View Hall 2 Thursday 9:00AM

Data Delivery with Drag and Drop Hall 2 Thursday 10:00AM

Page 278: Joe Cerra, UIKit Engineer - Apple Inc....•Advanced Animations with UIKit • Session 230 App Frameworks • Basics • Interactive and Interruptible Animations • New Property Animator

Previous Sessions

Core Animation Essentials WWDC 2011

Custom Transitions Using View Controllers WWDC 2013

Building Interruptible and Responsive Interactions WWDC 2014

Advanced Graphics and Animations for iOS Apps WWDC 2014

View Controller Advancements in iOS 8 WWDC 2014

Advances in UIKit Animations and Transitions WWDC 2016

Page 279: Joe Cerra, UIKit Engineer - Apple Inc....•Advanced Animations with UIKit • Session 230 App Frameworks • Basics • Interactive and Interruptible Animations • New Property Animator

Labs

Cocoa Touch and Haptics Lab Technology Lab C Friday 12:00PM

Page 280: Joe Cerra, UIKit Engineer - Apple Inc....•Advanced Animations with UIKit • Session 230 App Frameworks • Basics • Interactive and Interruptible Animations • New Property Animator

More Informationhttps://developer.apple.com/wwdc17/230

Page 281: Joe Cerra, UIKit Engineer - Apple Inc....•Advanced Animations with UIKit • Session 230 App Frameworks • Basics • Interactive and Interruptible Animations • New Property Animator