From 0991ad36d8651e4b11c3a27000593a5c1bef76b8 Mon Sep 17 00:00:00 2001 From: Reda Lemeden Date: Mon, 1 Jan 2018 21:12:33 +0100 Subject: [PATCH] Add completion handlers to all animate methods --- Demo/Source/Main.storyboard | 18 ++++++++++++++---- Demo/Source/ViewController.swift | 15 +++++++++++++-- Source/Classes/Animator.swift | 17 ++++++++++------- Source/Classes/FrameStore.swift | 2 +- Source/Classes/GIFAnimatable.swift | 17 +++++++++++------ Supporting Files/Info.plist | 2 +- 6 files changed, 50 insertions(+), 21 deletions(-) diff --git a/Demo/Source/Main.storyboard b/Demo/Source/Main.storyboard index dc0f65c..d848da3 100755 --- a/Demo/Source/Main.storyboard +++ b/Demo/Source/Main.storyboard @@ -4,7 +4,6 @@ - @@ -23,7 +22,7 @@ - + @@ -45,20 +44,30 @@ + + + + + @@ -68,6 +77,7 @@ + diff --git a/Demo/Source/ViewController.swift b/Demo/Source/ViewController.swift index 35da1c2..2ad3835 100755 --- a/Demo/Source/ViewController.swift +++ b/Demo/Source/ViewController.swift @@ -3,19 +3,22 @@ import Gifu class ViewController: UIViewController { @IBOutlet weak var imageView: GIFImageView! + @IBOutlet weak var imageDataLabel: UILabel! @IBAction func unwindToRootViewController(segue: UIStoryboardSegue) { } var currentGIFName: String = "mugen" { didSet { - imageView.animate(withGIFNamed: currentGIFName) + self.animate() } } @IBAction func toggleAnimation(_ sender: AnyObject) { if imageView.isAnimatingGIF { imageView.stopAnimatingGIF() + print(imageView.gifLoopDuration) } else { imageView.startAnimatingGIF() + print(imageView.gifLoopDuration) } } @@ -33,6 +36,14 @@ class ViewController: UIViewController { } override func viewDidAppear(_ animated: Bool) { - imageView.animate(withGIFNamed: currentGIFName) + self.animate() + } + + func animate() { + imageView.animate(withGIFNamed: currentGIFName) { + DispatchQueue.main.async { + self.imageDataLabel.text = self.currentGIFName.capitalized + " (\(self.imageView.frameCount) frames / \(String(format: "%.2f", self.imageView.gifLoopDuration))s)" + } + } } } diff --git a/Source/Classes/Animator.swift b/Source/Classes/Animator.swift index 69a7a5c..54f6d67 100644 --- a/Source/Classes/Animator.swift +++ b/Source/Classes/Animator.swift @@ -93,12 +93,11 @@ public class Animator { contentMode: contentMode, framePreloadCount: frameBufferCount, loopCount: loopCount) - frameStore?.shouldResizeFrames = shouldResizeFrames - frameStore?.prepareFrames(completionHandler) + frameStore!.shouldResizeFrames = shouldResizeFrames + frameStore!.prepareFrames(completionHandler) attachDisplayLink() } - /// Add the display link to the main run loop. private func attachDisplayLink() { displayLink.add(to: .main, forMode: RunLoopMode.commonModes) @@ -128,11 +127,13 @@ public class Animator { /// - parameter size: The target size of the individual frames. /// - parameter contentMode: The view content mode to use for the individual frames. /// - parameter loopCount: Desired number of loops, <= 0 for infinite loop. - func animate(withGIFNamed imageName: String, size: CGSize, contentMode: UIViewContentMode, loopCount: Int = 0) { + /// - parameter completionHandler: Completion callback function + func animate(withGIFNamed imageName: String, size: CGSize, contentMode: UIViewContentMode, loopCount: Int = 0, completionHandler: (() -> Void)? = nil) { prepareForAnimation(withGIFNamed: imageName, size: size, contentMode: contentMode, - loopCount: loopCount) + loopCount: loopCount, + completionHandler: completionHandler) startAnimating() } @@ -142,11 +143,13 @@ public class Animator { /// - parameter size: The target size of the individual frames. /// - parameter contentMode: The view content mode to use for the individual frames. /// - parameter loopCount: Desired number of loops, <= 0 for infinite loop. - func animate(withGIFData imageData: Data, size: CGSize, contentMode: UIViewContentMode, loopCount: Int = 0) { + /// - parameter completionHandler: Completion callback function + func animate(withGIFData imageData: Data, size: CGSize, contentMode: UIViewContentMode, loopCount: Int = 0, completionHandler: (() -> Void)? = nil) { prepareForAnimation(withGIFData: imageData, size: size, contentMode: contentMode, - loopCount: loopCount) + loopCount: loopCount, + completionHandler: completionHandler) startAnimating() } diff --git a/Source/Classes/FrameStore.swift b/Source/Classes/FrameStore.swift index 929b06d..6dff253 100644 --- a/Source/Classes/FrameStore.swift +++ b/Source/Classes/FrameStore.swift @@ -98,7 +98,7 @@ class FrameStore { animatedFrames.reserveCapacity(frameCount) preloadFrameQueue.async { self.setupAnimatedFrames() - if let handler = completionHandler { handler() } + completionHandler?() } } diff --git a/Source/Classes/GIFAnimatable.swift b/Source/Classes/GIFAnimatable.swift index e813bcf..e5baced 100644 --- a/Source/Classes/GIFAnimatable.swift +++ b/Source/Classes/GIFAnimatable.swift @@ -54,29 +54,34 @@ extension GIFAnimatable { /// /// - parameter imageName: The file name of the GIF in the main bundle. /// - parameter loopCount: Desired number of loops, <= 0 for infinite loop. - public func animate(withGIFNamed imageName: String, loopCount: Int = 0) { + /// - parameter completionHandler: Completion callback function + public func animate(withGIFNamed imageName: String, loopCount: Int = 0, completionHandler: (() -> Void)? = nil) { animator?.animate(withGIFNamed: imageName, size: frame.size, contentMode: contentMode, - loopCount: loopCount) + loopCount: loopCount, + completionHandler: completionHandler) } /// Prepare for animation and start animating immediately. /// /// - parameter imageData: GIF image data. /// - parameter loopCount: Desired number of loops, <= 0 for infinite loop. - public func animate(withGIFData imageData: Data, loopCount: Int = 0) { + /// - parameter completionHandler: Completion callback function + public func animate(withGIFData imageData: Data, loopCount: Int = 0, completionHandler: (() -> Void)? = nil) { animator?.animate(withGIFData: imageData, size: frame.size, contentMode: contentMode, - loopCount: loopCount) + loopCount: loopCount, + completionHandler: completionHandler) } /// Prepare for animation and start animating immediately. /// /// - parameter imageURL: GIF image url. /// - parameter loopCount: Desired number of loops, <= 0 for infinite loop. - public func animate(withGIFURL imageURL: URL, loopCount: Int = 0) { + /// - parameter completionHandler: Completion callback function + public func animate(withGIFURL imageURL: URL, loopCount: Int = 0, completionHandler: (() -> Void)? = nil) { let session = URLSession.shared let task = session.dataTask(with: imageURL) { (data, response, error) in @@ -85,7 +90,7 @@ extension GIFAnimatable { print("Error downloading gif:", error.localizedDescription, "at url:", imageURL.absoluteString) case (let data?, _, _): DispatchQueue.main.async { - self.animate(withGIFData: data, loopCount: loopCount) + self.animate(withGIFData: data, loopCount: loopCount, completionHandler: completionHandler) } default: () } diff --git a/Supporting Files/Info.plist b/Supporting Files/Info.plist index a96769c..12bd5e1 100644 --- a/Supporting Files/Info.plist +++ b/Supporting Files/Info.plist @@ -19,7 +19,7 @@ CFBundleSignature ???? CFBundleVersion - 135 + 136 NSPrincipalClass