1

I have a CAKeyframeAnimation that looks great in landscape but when the device rotates the animate is of course out of place compared to the rest of the content. Is there a way to adjust (scale) the path of an animation in progress?

Edit: Adding Code

        let circle = CAShapeLayer()
        circle.path = UIBezierPath(roundedRect: CGRect(x: -60.0, y: -60.0, width: 100.0, height: 100.0), cornerRadius: 50.0).cgPath
        circle.fillColor = UIColor.clear.cgColor
        circle.strokeColor = UIColor.blue.cgColor

        let animation = CAKeyframeAnimation(keyPath: "position")
        animation.duration = (path["endTime"] as! Double) - (path["startTime"] as! Double)
        animation.repeatCount = 0
        animation.path = (path as! UIBezierPath).cgPath
        animation.calculationMode = kCAAnimationPaced
        animation.fillMode = kCAFillModeForwards
        animation.isRemovedOnCompletion = false

        circle.add(animation, forKey: "position")
        self.view.layer.insertSublayer(circle, at: 5)

The problem is that the UIBezierPath is defined in either Portrait or Landscape (the app supports both) so playback at the same orientation that it was created is no problem, but if you rotate the device the Animation defined by the UIBezierPath should be updated for the new orientation. I'm just looking for a method of updating the CAKeyframeAnimation path to the new coordinate system while it is animating.

Chris
  • 955
  • 15
  • 20
  • Would you have any code to show us? –  Jan 22 '17 at 19:51
  • So you're saying you want to change the animation _while it is in the middle of animating_ because the user rotated the device? – matt Jan 22 '17 at 22:22
  • exactly! Because the coordinate system changes the path needs to update. I'm just not sure how to do that. – Chris Jan 22 '17 at 22:32

1 Answers1

0

I found that you can't adjust the path on the fly, but you can create a new path based on the points in the original and your calculated scale/translations.

To get the array of CGPoints from the UIBezierPath you can use this method: https://stackoverflow.com/a/36374209/1491675

For device rotation once the animation begins, keep a reference to the current point in the animation and on device rotation recalculate the path and replace the existing animation with a new one leaving out the part of the animation that has already occurred.

Community
  • 1
  • 1
Chris
  • 955
  • 15
  • 20
  • I don't understand why you don't just stop the animation dead when the rotation starts, leaving the view at the point where it is (the presentation layer will give you this information), and then start a new animation with a new path after the rotation finishes. – matt Feb 23 '17 at 15:43
  • you mean like I described above? "... on device rotation recalculate the path and replace the existing animation with a new one..." – Chris Feb 26 '17 at 15:24
  • 1
    Maybe it would help me (and others) if you showed the actual code. – matt Feb 26 '17 at 20:21