Add completion handlers to all animate methods

This commit is contained in:
Reda Lemeden 2018-01-01 21:12:33 +01:00
parent 7d627009f9
commit 0991ad36d8
6 changed files with 50 additions and 21 deletions

View File

@ -4,7 +4,6 @@
<adaptation id="fullscreen"/>
</device>
<dependencies>
<deployment identifier="iOS"/>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="13772"/>
<capability name="Aspect ratio constraints" minToolsVersion="5.1"/>
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
@ -23,7 +22,7 @@
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
<subviews>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="252" text="Tap the image to pause/resume. Swipe to change GIF." textAlignment="center" lineBreakMode="tailTruncation" numberOfLines="2" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="wsv-cU-WO5">
<rect key="frame" x="95.5" y="124.5" width="185" height="29"/>
<rect key="frame" x="95" y="125" width="185" height="29"/>
<constraints>
<constraint firstAttribute="width" relation="lessThanOrEqual" constant="200" id="73c-sg-Egr"/>
</constraints>
@ -32,7 +31,7 @@
<nil key="highlightedColor"/>
</label>
<imageView clipsSubviews="YES" contentMode="scaleAspectFit" horizontalHuggingPriority="251" verticalHuggingPriority="251" placeholderIntrinsicWidth="600" placeholderIntrinsicHeight="300" translatesAutoresizingMaskIntoConstraints="NO" id="FSz-xF-Xds" customClass="GIFImageView" customModule="Gifu">
<rect key="frame" x="0.0" y="203.5" width="375" height="300"/>
<rect key="frame" x="0.0" y="204" width="375" height="300"/>
<gestureRecognizers/>
<constraints>
<constraint firstAttribute="width" secondItem="FSz-xF-Xds" secondAttribute="height" multiplier="5:4" id="EOH-hn-KxM"/>
@ -45,20 +44,30 @@
</connections>
</imageView>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="252" text="Gifu" textAlignment="center" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="c8Y-41-BaC">
<rect key="frame" x="170.5" y="100" width="34" height="20.5"/>
<rect key="frame" x="171" y="100" width="34" height="21"/>
<fontDescription key="fontDescription" type="boldSystem" pointSize="17"/>
<color key="textColor" red="0.99144423007965088" green="0.56549066305160522" blue="0.033751130104064941" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<nil key="highlightedColor"/>
</label>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Label" textAlignment="center" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="XcY-7q-76n">
<rect key="frame" x="0.5" y="514" width="375" height="18"/>
<fontDescription key="fontDescription" type="italicSystem" pointSize="15"/>
<color key="textColor" white="0.66666666669999997" alpha="1" colorSpace="calibratedWhite"/>
<nil key="highlightedColor"/>
</label>
</subviews>
<color key="backgroundColor" cocoaTouchSystemColor="darkTextColor"/>
<color key="tintColor" red="0.99144423007965088" green="0.56549066305160522" blue="0.033751130104064941" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<constraints>
<constraint firstItem="XcY-7q-76n" firstAttribute="width" secondItem="FSz-xF-Xds" secondAttribute="width" id="306-mf-Sm0"/>
<constraint firstAttribute="trailing" secondItem="FSz-xF-Xds" secondAttribute="trailing" id="8kQ-x1-WJl"/>
<constraint firstItem="XcY-7q-76n" firstAttribute="top" secondItem="FSz-xF-Xds" secondAttribute="bottom" constant="10" id="BH2-vh-hUc"/>
<constraint firstItem="XcY-7q-76n" firstAttribute="centerX" secondItem="FSz-xF-Xds" secondAttribute="centerX" id="FBH-PS-mfM"/>
<constraint firstItem="c8Y-41-BaC" firstAttribute="top" secondItem="jyV-Pf-zRb" secondAttribute="bottom" constant="80" id="JHy-q1-JuJ"/>
<constraint firstAttribute="centerX" secondItem="c8Y-41-BaC" secondAttribute="centerX" id="Kc0-P5-KMZ"/>
<constraint firstItem="FSz-xF-Xds" firstAttribute="leading" secondItem="kh9-bI-dsS" secondAttribute="leading" id="O4L-QH-SvV"/>
<constraint firstItem="FSz-xF-Xds" firstAttribute="top" secondItem="wsv-cU-WO5" secondAttribute="bottom" constant="50" id="ODd-UW-Pca"/>
<constraint firstItem="2fi-mo-0CV" firstAttribute="top" relation="greaterThanOrEqual" secondItem="XcY-7q-76n" secondAttribute="bottom" constant="12" id="VEE-1g-0W4"/>
<constraint firstItem="wsv-cU-WO5" firstAttribute="top" secondItem="c8Y-41-BaC" secondAttribute="bottom" constant="4" id="ZG4-fK-WvN"/>
<constraint firstAttribute="centerX" secondItem="FSz-xF-Xds" secondAttribute="centerX" id="oih-yH-vRh"/>
<constraint firstAttribute="centerX" secondItem="wsv-cU-WO5" secondAttribute="centerX" id="yLb-zR-gfU"/>
@ -68,6 +77,7 @@
<nil key="simulatedTopBarMetrics"/>
<nil key="simulatedBottomBarMetrics"/>
<connections>
<outlet property="imageDataLabel" destination="XcY-7q-76n" id="8b5-Hu-aDc"/>
<outlet property="imageView" destination="FSz-xF-Xds" id="gtV-MK-Fwd"/>
</connections>
</viewController>

View File

@ -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)"
}
}
}
}

View File

@ -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()
}

View File

@ -98,7 +98,7 @@ class FrameStore {
animatedFrames.reserveCapacity(frameCount)
preloadFrameQueue.async {
self.setupAnimatedFrames()
if let handler = completionHandler { handler() }
completionHandler?()
}
}

View File

@ -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: ()
}

View File

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