Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Gif Loop Delegate Callback And Max Repeat Count Reached Too Early #860

Closed
3 tasks done
mliberatore opened this issue Feb 13, 2018 · 2 comments · Fixed by #861
Closed
3 tasks done

Gif Loop Delegate Callback And Max Repeat Count Reached Too Early #860

mliberatore opened this issue Feb 13, 2018 · 2 comments · Fixed by #861

Comments

@mliberatore
Copy link
Contributor

Check List

Thanks for considering to open an issue. Before you submit your issue, please confirm these boxes are checked.

Issue Description

AnimatedImageViewDelegate callbacks happen too soon when animating a gif that has more frames than the framePreloadCount. Also, on the first loop, a frame is skipped because of an off-by-one error.

What

When the buffer for an animated image (imageView.framePreloadCount) is smaller than the number of frames in the animated image, the delegate method animatedImageView(_:didPlayAnimationLoops:) is called too soon. Instead of being called at the end of the loop, it is called when the number of frames in the buffer have been displayed. That means if you have a gif with 10 frames, and a framePreloadCount of 5, the delegate method will be called after 5 frames have been displayed. Similarly, if you’re using imageView.repeatCount = .once, the gif will stop playback after 5 frames instead of 10.

Reproduce

[The steps to reproduce this issue. What is the url you were trying to load, where did you put your code, etc.]

I’ll use this gif for demonstration, as it is easier to see what’s happening. It’s got 10 frames, and each frame displays a number, 0 thru 9. (External link).

example-gif

To demonstrate this issue, we use the following code in a view controller, setting the framePreloadCount to 5, when we know the gif has 10 frames.

override func viewDidLoad() {
    super.viewDidLoad()
    
    imageView.delegate = self
    imageView.autoPlayAnimatedImage = false
    imageView.framePreloadCount = 5

    let url = URL(string: "https://media.giphy.com/media/sS8US86vlpHK8/giphy.gif")!
    imageView.kf.setImage(with: url)
}

When we tap a play button, animation begins:

@IBAction func playButtonTapped(_ sender: UIButton) {
    playButton.isEnabled = false
    imageView.startAnimating()
}

And finally, when the delegate method is called after a loop, we stop animating, and re-enable the play button:

func animatedImageView(_ imageView: AnimatedImageView, didPlayAnimationLoops count: UInt) {
    imageView.stopAnimating()
    
    playButton.isEnabled = true
}

The following shows this sample app running. Notice the two issues:

  1. On the first loop, the frame that displays the number “5” is skipped.
  2. Only 5 frames are shown before the delegate callback occurs.

feb-13-2018 10-18-22

Other Comment

  1. The sample project I created that demonstrates this issue is here: KingfisherLooping.zip
  2. I have a fix incoming for this. I will open a pull request.
@onevcat
Copy link
Owner

onevcat commented Feb 13, 2018

Wow.

I am traveling now so I have no chance to look at it in detail. But you are definitely right according to the screenshot. The p-r also looks great! I’d check it as soon as my feet in land!

Thank you! 😃

@mliberatore
Copy link
Contributor Author

Sounds great, and thank you!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants