Support loading remote GIFs

- Closes #111
This commit is contained in:
Shubham 2017-07-19 15:04:33 +05:30 committed by Reda Lemeden
parent 6d19f73aad
commit 693dbc9eb4
3 changed files with 93 additions and 13 deletions

View File

@ -73,7 +73,11 @@ public class Animator {
let imagePath = Bundle.main.url(forResource: extensionRemoved, withExtension: "gif"),
let data = try? Data(contentsOf: imagePath) else { return }
prepareForAnimation(withGIFData: data, size: size, contentMode: contentMode, loopCount: loopCount, completionHandler: completionHandler)
prepareForAnimation(withGIFData: data,
size: size,
contentMode: contentMode,
loopCount: loopCount,
completionHandler: completionHandler)
}
/// Prepares the animator instance for animation.
@ -84,7 +88,11 @@ public class Animator {
/// - parameter loopCount: Desired number of loops, <= 0 for infinite loop.
/// - parameter completionHandler: Completion callback function
func prepareForAnimation(withGIFData imageData: Data, size: CGSize, contentMode: UIViewContentMode, loopCount: Int = 0, completionHandler: (() -> Void)? = nil) {
frameStore = FrameStore(data: imageData, size: size, contentMode: contentMode, framePreloadCount: frameBufferCount, loopCount: loopCount)
frameStore = FrameStore(data: imageData,
size: size,
contentMode: contentMode,
framePreloadCount: frameBufferCount,
loopCount: loopCount)
frameStore?.shouldResizeFrames = shouldResizeFrames
frameStore?.prepareFrames(completionHandler)
attachDisplayLink()
@ -121,7 +129,10 @@ public class Animator {
/// - 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) {
prepareForAnimation(withGIFNamed: imageName, size: size, contentMode: contentMode, loopCount: loopCount)
prepareForAnimation(withGIFNamed: imageName,
size: size,
contentMode: contentMode,
loopCount: loopCount)
startAnimating()
}
@ -132,7 +143,10 @@ public class Animator {
/// - 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) {
prepareForAnimation(withGIFData: imageData, size: size, contentMode: contentMode, loopCount: loopCount)
prepareForAnimation(withGIFData: imageData,
size: size,
contentMode: contentMode,
loopCount: loopCount)
startAnimating()
}

View File

@ -1,6 +1,7 @@
import Foundation
/// The protocol that view classes need to conform to to enable animated GIF support.
public protocol GIFAnimatable: class {
/// Responsible for managing the animation frames.
var animator: Animator? { get set }
@ -33,7 +34,7 @@ extension GIFAnimatable {
public var gifLoopDuration: TimeInterval {
return animator?.loopDuration ?? 0
}
/// Returns the active frame if available.
public var activeFrame: UIImage? {
return animator?.activeFrame()
@ -54,7 +55,10 @@ 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) {
animator?.animate(withGIFNamed: imageName, size: frame.size, contentMode: contentMode, loopCount: loopCount)
animator?.animate(withGIFNamed: imageName,
size: frame.size,
contentMode: contentMode,
loopCount: loopCount)
}
/// Prepare for animation and start animating immediately.
@ -62,27 +66,89 @@ extension GIFAnimatable {
/// - parameter imageData: GIF image data.
/// - parameter loopCount: Desired number of loops, <= 0 for infinite loop.
public func animate(withGIFData imageData: Data, loopCount: Int = 0) {
animator?.animate(withGIFData: imageData, size: frame.size, contentMode: contentMode, loopCount: loopCount)
animator?.animate(withGIFData: imageData,
size: frame.size,
contentMode: contentMode,
loopCount: loopCount)
}
/// 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) {
let session = URLSession.shared
let task = session.dataTask(with: imageURL) { (data, response, error) in
switch (data, response, error) {
case (.none, _, let error?):
print("Error downloading gif:", error.localizedDescription, "at url:", imageURL.absoluteString)
case (let data?, _, _):
DispatchQueue.main.async {
self.animate(withGIFData: data, loopCount: loopCount)
}
default: ()
}
}
task.resume()
}
/// Prepares the animator instance for animation.
///
/// - parameter imageName: The file name of the GIF in the main bundle.
/// - parameter loopCount: Desired number of loops, <= 0 for infinite loop.
public func prepareForAnimation(withGIFNamed imageName: String, loopCount: Int = 0, completionHandler: (() -> Void)? = nil) {
animator?.prepareForAnimation(withGIFNamed: imageName, size: frame.size, contentMode: contentMode, loopCount: loopCount, completionHandler: completionHandler)
public func prepareForAnimation(withGIFNamed imageName: String,
loopCount: Int = 0,
completionHandler: (() -> Void)? = nil) {
animator?.prepareForAnimation(withGIFNamed: imageName,
size: frame.size,
contentMode: contentMode,
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 prepareForAnimation(withGIFData imageData: Data, loopCount: Int = 0, completionHandler: (() -> Void)? = nil) {
public func prepareForAnimation(withGIFData imageData: Data,
loopCount: Int = 0,
completionHandler: (() -> Void)? = nil) {
if var imageContainer = self as? ImageContainer {
imageContainer.image = UIImage(data: imageData)
}
animator?.prepareForAnimation(withGIFData: imageData, size: frame.size, contentMode: contentMode, loopCount: loopCount, completionHandler: completionHandler)
animator?.prepareForAnimation(withGIFData: imageData,
size: frame.size,
contentMode: contentMode,
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 prepareForAnimation(withGIFURL imageURL: URL,
loopCount: Int = 0,
completionHandler: (() -> Void)? = nil) {
let session = URLSession.shared
let task = session.dataTask(with: imageURL) { (data, response, error) in
switch (data, response, error) {
case (.none, _, let error?):
print("Error downloading gif:", error.localizedDescription, "at url:", imageURL.absoluteString)
case (let data?, _, _):
DispatchQueue.main.async {
self.prepareForAnimation(withGIFData: data,
loopCount: loopCount,
completionHandler: completionHandler)
}
default: ()
}
}
task.resume()
}
/// Stop animating and free up GIF data from memory.

View File

@ -19,7 +19,7 @@
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleVersion</key>
<string>128</string>
<string>133</string>
<key>NSPrincipalClass</key>
<string></string>
</dict>