Sdwebimage: Prefetch cause the gif in modal to stop its animation

Created on 12 Nov 2019  路  5Comments  路  Source: SDWebImage/SDWebImage

New Issue Checklist

Issue Info

Info | Value
---|---
Platform Name | iOS
Platform Version | 13.3
SDWebImage Version | 5.3.1
Integration Method | SPM
Xcode Version | Xcode Version 11.2.1 (11B53)
Repro rate | all the time (100%)
Repro with our demo prj | n/a
Demo project link | https://github.com/maundytime/Demo

Issue Description and Steps

Reproduce way: Install the demo above, at first vc, I prefetch a gif, then modal second vc, I do pan on it and change it size, the gif will stop animating.

After first installation, the problem is gone, seems that gif data is cached in disk.

Or if I don't prefetch at first installation, the problem is not exist either.

This problem is found when I try to do vc dismiss transition.

Hope for some instructions or suggestions. Thank you : )

animated image

All 5 comments

I try you demo, maybe I get the reason. But at first, I want to talk about some basic background knowledge.

The reason is about the animation behavior of UIImageView and UIAnimatedImage. Not SDAnimatedImageView.

UIImageView supports animation, you can see these APIs: startAnimating
When a UIImage is created by animatedImage(with:) API, it's a UIAnimatedImage class.

UIImageView's animation behavior is: When the view is during animation (in your ViewController transition, for example), the frame animation will stop. This is known behavior. I don't want to tell the details here, but a hint: UIImageView's animation is based on CALayer key-frame animation, when ViewControll transition begins, all previous CALayer animation will be implicit disable. You can try your demo by change the type SDAnimatedImageView -> UIImageView.

However, SDAnimatedImageView does not have this behavior. It do animation based on a timer callback and supply CGImage to CALayer. Until you call stopAnimating API, it still get callback and render frame. (note we supports to disable animation when view disappears, but will not cause anything issue when you do viewController transition or custom Core Animation.

So, Why prefetcher cause issues ?

It's because, when you call SDWebImagePrefetcher with the default arguments, we will not produce SDAnimatedImage, we will produce UIAnimatedImage. When this UIAnimatedImage meet SDAnimatedImageView, it will cause the SDAnimatedImageView do the UIImageView based animation behavior (from Wiki) So, it stop when pop viewController.

image

When SDAnimatedImageView callsd_setImage(:_) API, it provide a default context option: .animatedImageClass

When you secondlly query that image, the image is queried from disk cache, and we found that you use the the .animatedImageClass, and give the SDAnimatedImage instead of UIAnimatedImage. So the animation does not stop when pop viewController.

To solve the issue, you can do either one of two things

  1. If you want to prefetch GIF and render on a SDAnimatedImageView, provide the .animatedImageClass context option as well.
SDWebImagePrefetcher.shared.context = [.animatedImageClass : SDAnimatedImage.Self]
  1. You can also try to use this context option: .matchAnimatedImageClass, to ensure the image class is matched. So that even the prefetcher cached the UIImage, your sd_setImage(_:) on SDAnimatedImageView call, will ignore that cache, and requery to generate a SDAnimatedImage
SDWebImagePrefetcher.shared.context = [.animatedImageClass : SDAnimatedImage.Self, .matchAnimatedImageClass : true]

I see, SDAnimatedImage and SDWebImagePrefetcher are independent from each other. So SDWebImagePrefetcher use system UIAnimatedImage as default behavior.

Your two suggestions are sweet and worked. My problem solved.

Thank you very much for reply with so much detail. It would be a huge work for me to figure out this by myself.

Actually, this is a good catch for Animation Image View + Prefetcher things. I'll update this point into the wiki here, to let user know that prefetch a GIF (used SDAnimatedImageView) should use extra option.

@maundytime Updated the wiki about prefetcher and this animated image view. Maybe this can be helpful for other users.

https://github.com/SDWebImage/SDWebImage/wiki/How-to-use#using-sdwebimageprefetcher

Was this page helpful?
0 / 5 - 0 ratings

Related issues

Binusz picture Binusz  路  4Comments

MagLiC picture MagLiC  路  3Comments

ku8ar picture ku8ar  路  4Comments

ericeddy picture ericeddy  路  6Comments

paul-lavoine picture paul-lavoine  路  4Comments