How to tame Core Animation

How to tame Core Animation

Core Animation is a wild animal - powerful and beautiful but hard to familiarize and tame. Yet, when you befriend this animal, you can do great things with app visuals. Here's my story on creating a powerful animation for Apple devices in Swift with lots of experiments, limit testing and some math.

6c9d1e82615877b0b2866f82cbf5f557?s=128

Kristaps Grinbergs

November 08, 2019
Tweet

Transcript

  1. How to tame Core Animation

  2. tame adjective Reduced from a state of native wildness especially

    so as to be tractable and useful to humans
  3. None
  4. About me 15+ years of experience Swift developer Open source

  5. None
  6. a queue management system

  7. Serving millions of people every month

  8. Mr. Byte

  9. Animations = easy?

  10. – Soroush Khanlou “Animations in iOS are easy, except when

    they’re not.”
  11. Intro to Core Animation Animation path property Real life example

    Agenda
  12. SwiftUI

  13. None
  14. What is animation?

  15. What is animation?

  16. About Core Animation

  17. ➡ Layer Kit ➡ August 7, 2006 WWDC ➡ Mac

    OS X 10.5 Leopard ➡ Created by John Harper About Core Animation
  18. None
  19. Core animation

  20. Core Animation provides high frame rates and smooth animations without

    burdening the CPU and slowing down your app. – Apple Documentation
  21. NO. Is Core Animation == UIView animations ?

  22. None
  23. None
  24. Core Graphics

  25. developer.apple.com

  26. Core Animation ???

  27. ➡ iOS, macOS and tvOS ➡ Hardware accelerated GPU ➡

    Runs on separate process Core Animation ???
  28. Time of completion & frames

  29. Animation Time Span New Value Existing Value frame.origin.x CALayers

  30. 0.25 seconds * 60 frames = 15 locations Interpolation example

  31. Interpolation types

  32. animation.timingFunction = CAMediaTimingFunction(name: .linear) // default // easeIn // easeInEaseOut

    // easeOut // linear
  33. Animation types

  34. Animation types ➡ Basic Animation ➡ Keyframe Animations ➡ Grouping

    Animations
  35. setBounds CALayers

  36. None
  37. Layers vs Views

  38. Views Layers vs complex, Auto Layout user interaction CPU powered

    restricted no responder chain drawn on the GPU
  39. CAShapeLayer

  40. let bezierPath = UIBezierPath() bezierPath.move(to: point1) bezierPath.addLine(to: point2) bezierPath.addLine(to: point3)

    bezierPath.addLine(to: point1) bezierPath.close() let shapeLayer = CAShapeLayer() shapeLayer.path = bezierPath.cgPath shapeLayer.lineWidth = 0 shapeLayer.fillColor = fillColor.cgColor self.layer.addSublayer(shapeLayer)
  41. let bezierPath = UIBezierPath() bezierPath.move(to: point1) bezierPath.addLine(to: point2) bezierPath.addLine(to: point3)

    bezierPath.addLine(to: point1) bezierPath.close() let shapeLayer = CAShapeLayer() shapeLayer.path = bezierPath.cgPath shapeLayer.lineWidth = 0 shapeLayer.fillColor = fillColor.cgColor self.layer.addSublayer(shapeLayer)
  42. let bezierPath = UIBezierPath() bezierPath.move(to: point1) bezierPath.addLine(to: point2) bezierPath.addLine(to: point3)

    bezierPath.addLine(to: point1) bezierPath.close() let shapeLayer = CAShapeLayer() shapeLayer.path = bezierPath.cgPath shapeLayer.lineWidth = 1 shapeLayer.fillColor = fillColor.cgColor self.layer.addSublayer(shapeLayer)
  43. let bezierPath = UIBezierPath() bezierPath.move(to: point1) bezierPath.addLine(to: point2) bezierPath.addLine(to: point3)

    bezierPath.addLine(to: point1) bezierPath.close() let shapeLayer = CAShapeLayer() shapeLayer.path = bezierPath.cgPath shapeLayer.lineWidth = 1 shapeLayer.fillColor = fillColor.cgColor self.layer.addSublayer(shapeLayer)
  44. None
  45. None
  46. let pathAnimation = CABasicAnimation(keyPath: #keyPath(CAShapeLayer.path)) shapeLayer.add(pathAnimation, forKey: "pathAnimation") pathAnimation.toValue =

    triangle.cgPath pathAnimation.duration = 1.0 pathAnimation.timingFunction = CAMediaTimingFunction(name: .easeInEaseOut) pathAnimation.autoreverses = true pathAnimation.repeatCount = .greatestFiniteMagnitude
  47. let pathAnimation = CABasicAnimation(keyPath: #keyPath(CAShapeLayer.path)) shapeLayer.add(pathAnimation, forKey: "pathAnimation") pathAnimation.toValue =

    triangle.cgPath pathAnimation.duration = 1.0 pathAnimation.timingFunction = CAMediaTimingFunction(name: .easeInEaseOut) pathAnimation.autoreverses = true pathAnimation.repeatCount = .greatestFiniteMagnitude
  48. let pathAnimation = CABasicAnimation(keyPath: #keyPath(CAShapeLayer.path)) shapeLayer.add(pathAnimation, forKey: "pathAnimation") pathAnimation.toValue =

    triangle.cgPath pathAnimation.duration = 1.0 pathAnimation.timingFunction = CAMediaTimingFunction(name: .easeInEaseOut) pathAnimation.autoreverses = true pathAnimation.repeatCount = .greatestFiniteMagnitude
  49. let pathAnimation = CABasicAnimation(keyPath: #keyPath(CAShapeLayer.path)) shapeLayer.add(pathAnimation, forKey: "pathAnimation") pathAnimation.toValue =

    triangle.cgPath pathAnimation.duration = 1.0 pathAnimation.timingFunction = CAMediaTimingFunction(name: .easeInEaseOut) pathAnimation.autoreverses = true pathAnimation.repeatCount = .greatestFiniteMagnitude
  50. None
  51. let animationGroup = CAAnimationGroup() animationGroup.animations = [...] animationGroup.autoreverses = true

    animationGroup.repeatCount = .greatestFiniteMagnitude animationGroup.duration = 2.0
  52. let animationGroup = CAAnimationGroup() animationGroup.animations = [...] animationGroup.autoreverses = true

    animationGroup.repeatCount = .greatestFiniteMagnitude animationGroup.duration = 2.0
  53. let animationGroup = CAAnimationGroup() animationGroup.animations = [...] animationGroup.autoreverses = true

    animationGroup.repeatCount = .greatestFiniteMagnitude animationGroup.duration = 2.0
  54. None
  55. None
  56. None
  57. None
  58. None
  59. None
  60. Snøhetta to build Shanghai Grand Opera House with spiral staircase

    roof
  61. Cartesian Coordinates Polar Coordinates

  62. None
  63. None
  64. fassko/animatingLavaTriangles

  65. Experiment with animations

  66. None
  67. Know when it’s too much CA is powerful & well

    documented API Hard to do something out of bounds Conclusions
  68. None
  69. fassko www.kristaps.me