I have two methods of achieving the same sprite animation:
- An
UIImage
that animates an array of 6 images usinganimatedImage(with:duration:)
. - A
UIView
with itsCALayer
’scontents
property set to a sprite atlas image—the layer’scontentsRect
property is updated via aCADisplayLink
. To ensure frame rate independence, I’m accumulating delta time (ordisplayLink.duration
) until an image should change. When the image changes, I subtract the elapsed time needed for one image from the accumulated delta time and the cycle continues.
Both methods work great and look almost identical (if not identical) on my iPhone. However, when running in Simulator, #1 appears to animate at the device speed, while #2 appears to animate noticeably slower.
When comparing the FPS from my device and the simulator, the device averages around 59.9 to 60 FPS, while Simulator shows a constant 60 FPS; this doesn't account for #2 appearing to be noticeably slower.
So, why is #2 slower in Simulator?
Code for #1:
UIImage.animatedImage(with: spriteImages, duration: animationDuration)
Code for #2:
func update(_ seconds: TimeInterval) {
accumulatedSeconds += seconds
// `poseDuration` is `animationDuration / 6`.
guard accumulatedSeconds >= poseDuration else { return }
switch currentFrame {
case 6:
myView.layer.contentsRect = CGRect(x: 0, y: 0, width: width, height: 1)
currentFrame = 1
default:
myView.layer.contentsRect = CGRect(x: width * Double(currentFrame), y: 0, width: width, height: 1)
currentFrame += 1
}
accumulatedSeconds -= poseDuration
}
Basically, CADisplayLink doesn't work well in the simulator. Test on a device only.