Reorganize project using Synx

This commit is contained in:
Reda Lemeden 2016-10-01 13:41:22 +02:00
parent 97f004413f
commit b5c553bba2
28 changed files with 101 additions and 107 deletions

View File

@ -18,14 +18,14 @@
/* End PBXBuildFile section */
/* Begin PBXFileReference section */
0009FCE61D16A4AB0038DC85 /* earth.gif */ = {isa = PBXFileReference; lastKnownFileType = image.gif; name = earth.gif; path = GIFs/earth.gif; sourceTree = SOURCE_ROOT; };
0009FCE61D16A4AB0038DC85 /* earth.gif */ = {isa = PBXFileReference; lastKnownFileType = image.gif; path = earth.gif; sourceTree = "<group>"; };
002A1BF91D161D33005ABBD0 /* Gifu.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Gifu.framework; path = "../../../../Library/Developer/Xcode/DerivedData/Gifu-gwslszlwadetledwfipapwloqzrw/Build/Products/Debug-iphonesimulator/Gifu.framework"; sourceTree = "<group>"; };
002A1BFB1D1624D0005ABBD0 /* mugen.gif */ = {isa = PBXFileReference; lastKnownFileType = image.gif; name = mugen.gif; path = ../GIFs/mugen.gif; sourceTree = "<group>"; };
007380221B279644008DAD5C /* Default-568h@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "Default-568h@2x.png"; path = "../Default-568h@2x.png"; sourceTree = "<group>"; };
002A1BFB1D1624D0005ABBD0 /* mugen.gif */ = {isa = PBXFileReference; lastKnownFileType = image.gif; name = mugen.gif; path = ../../../GifuTests/Images/mugen.gif; sourceTree = "<group>"; };
007380221B279644008DAD5C /* Default-568h@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "Default-568h@2x.png"; sourceTree = "<group>"; };
9D25870519BCCB0F00A55A18 /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
9D98823719BC69CA00B790C6 /* Demo.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Demo.app; sourceTree = BUILT_PRODUCTS_DIR; };
9D98823C19BC69CA00B790C6 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = AppDelegate.swift; path = classes/AppDelegate.swift; sourceTree = "<group>"; };
9D98823E19BC69CA00B790C6 /* ViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = ViewController.swift; path = classes/ViewController.swift; sourceTree = "<group>"; };
9D98823C19BC69CA00B790C6 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = "<group>"; };
9D98823E19BC69CA00B790C6 /* ViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ViewController.swift; sourceTree = "<group>"; };
9D98824319BC69CA00B790C6 /* Images.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Images.xcassets; sourceTree = "<group>"; };
9D98825919BC69F600B790C6 /* Main.storyboard */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.storyboard; path = Main.storyboard; sourceTree = "<group>"; };
/* End PBXFileReference section */
@ -53,9 +53,9 @@
9D98822E19BC69CA00B790C6 = {
isa = PBXGroup;
children = (
9D98823919BC69CA00B790C6 /* Source */,
9D98823819BC69CA00B790C6 /* Products */,
002A1BF81D161D32005ABBD0 /* Frameworks */,
9D98823819BC69CA00B790C6 /* Products */,
9D98823919BC69CA00B790C6 /* Source */,
);
sourceTree = "<group>";
};
@ -70,25 +70,24 @@
9D98823919BC69CA00B790C6 /* Source */ = {
isa = PBXGroup;
children = (
9D98823C19BC69CA00B790C6 /* AppDelegate.swift */,
9D98823E19BC69CA00B790C6 /* ViewController.swift */,
9D98825919BC69F600B790C6 /* Main.storyboard */,
9D98824319BC69CA00B790C6 /* Images.xcassets */,
9D98823A19BC69CA00B790C6 /* Supporting Files */,
9D98823C19BC69CA00B790C6 /* AppDelegate.swift */,
9D98824319BC69CA00B790C6 /* Images.xcassets */,
9D98825919BC69F600B790C6 /* Main.storyboard */,
9D98823E19BC69CA00B790C6 /* ViewController.swift */,
);
name = Source;
path = demo;
path = Source;
sourceTree = "<group>";
};
9D98823A19BC69CA00B790C6 /* Supporting Files */ = {
isa = PBXGroup;
children = (
0009FCE61D16A4AB0038DC85 /* earth.gif */,
002A1BFB1D1624D0005ABBD0 /* mugen.gif */,
007380221B279644008DAD5C /* Default-568h@2x.png */,
9D25870519BCCB0F00A55A18 /* Info.plist */,
0009FCE61D16A4AB0038DC85 /* earth.gif */,
002A1BFB1D1624D0005ABBD0 /* mugen.gif */,
);
name = "Supporting Files";
path = "Supporting Files";
sourceTree = "<group>";
};
/* End PBXGroup section */
@ -259,7 +258,7 @@
buildSettings = {
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
FRAMEWORK_SEARCH_PATHS = "$(inherited)";
INFOPLIST_FILE = demo/Info.plist;
INFOPLIST_FILE = "Source/Supporting Files/Info.plist";
IPHONEOS_DEPLOYMENT_TARGET = 9.0;
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
PRODUCT_BUNDLE_IDENTIFIER = co.kaishin.gifu.demo;
@ -274,7 +273,7 @@
buildSettings = {
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
FRAMEWORK_SEARCH_PATHS = "$(inherited)";
INFOPLIST_FILE = demo/Info.plist;
INFOPLIST_FILE = "Source/Supporting Files/Info.plist";
IPHONEOS_DEPLOYMENT_TARGET = 9.0;
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
PRODUCT_BUNDLE_IDENTIFIER = co.kaishin.gifu.demo;

View File

Before

Width:  |  Height:  |  Size: 31 KiB

After

Width:  |  Height:  |  Size: 31 KiB

View File

Before

Width:  |  Height:  |  Size: 10 KiB

After

Width:  |  Height:  |  Size: 10 KiB

View File

Before

Width:  |  Height:  |  Size: 18 KiB

After

Width:  |  Height:  |  Size: 18 KiB

View File

Before

Width:  |  Height:  |  Size: 13 MiB

After

Width:  |  Height:  |  Size: 13 MiB

View File

@ -3,6 +3,8 @@ import Gifu
class ViewController: UIViewController {
@IBOutlet weak var imageView: GIFImageView!
@IBAction func unwindToRootViewController(segue: UIStoryboardSegue) { }
var currentGIFName: String = "mugen" {
didSet {
imageView.animate(withGIFNamed: currentGIFName)
@ -33,6 +35,4 @@ class ViewController: UIViewController {
override func viewDidAppear(_ animated: Bool) {
imageView.animate(withGIFNamed: currentGIFName)
}
@IBAction func unwindToRootViewController(segue: UIStoryboardSegue) { }
}

View File

@ -11,16 +11,15 @@
0036ABB91BBD1D1400C6CC3D /* nailed.gif in Resources */ = {isa = PBXBuildFile; fileRef = 0036ABB81BBD1D1400C6CC3D /* nailed.gif */; };
005656ED1A6F14D6008A0ED1 /* FrameStore.swift in Sources */ = {isa = PBXBuildFile; fileRef = 005656EC1A6F14D6008A0ED1 /* FrameStore.swift */; };
005656EF1A6F1C26008A0ED1 /* GIFImageView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 005656EE1A6F1C26008A0ED1 /* GIFImageView.swift */; };
007E08441BD95E6200883D0C /* ArrayExtension.swift in Sources */ = {isa = PBXBuildFile; fileRef = 007E08431BD95E6200883D0C /* ArrayExtension.swift */; };
007E08441BD95E6200883D0C /* Array.swift in Sources */ = {isa = PBXBuildFile; fileRef = 007E08431BD95E6200883D0C /* Array.swift */; };
00978B6C1D9C6D2A00A6575F /* Animator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 00978B6B1D9C6D2A00A6575F /* Animator.swift */; };
00978B6E1D9FA99D00A6575F /* AnimatorDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 00978B6D1D9FA99D00A6575F /* AnimatorDelegate.swift */; };
009BD1391BBC7F6500FC982B /* GifuTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 009BD1381BBC7F6500FC982B /* GifuTests.swift */; };
009BD13B1BBC7F6500FC982B /* Gifu.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 00B8C73E1A364DA400C188E7 /* Gifu.framework */; };
009BD1441BBC93C800FC982B /* CGSizeExtension.swift in Sources */ = {isa = PBXBuildFile; fileRef = 009BD1431BBC93C800FC982B /* CGSizeExtension.swift */; };
009BD1441BBC93C800FC982B /* CGSize.swift in Sources */ = {isa = PBXBuildFile; fileRef = 009BD1431BBC93C800FC982B /* CGSize.swift */; };
00B8C75F1A364DCE00C188E7 /* ImageSourceHelpers.swift in Sources */ = {isa = PBXBuildFile; fileRef = 00B8C75C1A364DCE00C188E7 /* ImageSourceHelpers.swift */; };
00B8C7961A3650EE00C188E7 /* Gifu.h in Headers */ = {isa = PBXBuildFile; fileRef = 00B8C7951A3650EE00C188E7 /* Gifu.h */; settings = {ATTRIBUTES = (Public, ); }; };
00BF42CC1D99A1DC00C6F28D /* GIFAnimatable.swift in Sources */ = {isa = PBXBuildFile; fileRef = 00BF42CB1D99A1DC00C6F28D /* GIFAnimatable.swift */; };
EAF49C7F1A3A4DE000B395DF /* UIImageExtension.swift in Sources */ = {isa = PBXBuildFile; fileRef = EAF49C7E1A3A4DE000B395DF /* UIImageExtension.swift */; };
EAF49C7F1A3A4DE000B395DF /* UIImage.swift in Sources */ = {isa = PBXBuildFile; fileRef = EAF49C7E1A3A4DE000B395DF /* UIImage.swift */; };
EAF49CB11A3B6EEB00B395DF /* AnimatedFrame.swift in Sources */ = {isa = PBXBuildFile; fileRef = EAF49CB01A3B6EEB00B395DF /* AnimatedFrame.swift */; };
/* End PBXBuildFile section */
@ -35,23 +34,22 @@
/* End PBXContainerItemProxy section */
/* Begin PBXFileReference section */
0036ABB61BBD1D0B00C6CC3D /* mugen.gif */ = {isa = PBXFileReference; lastKnownFileType = image.gif; name = mugen.gif; path = Demo/GIFs/mugen.gif; sourceTree = SOURCE_ROOT; };
0036ABB81BBD1D1400C6CC3D /* nailed.gif */ = {isa = PBXFileReference; lastKnownFileType = image.gif; name = nailed.gif; path = Demo/GIFs/nailed.gif; sourceTree = SOURCE_ROOT; };
0036ABB61BBD1D0B00C6CC3D /* mugen.gif */ = {isa = PBXFileReference; lastKnownFileType = image.gif; path = mugen.gif; sourceTree = "<group>"; };
0036ABB81BBD1D1400C6CC3D /* nailed.gif */ = {isa = PBXFileReference; lastKnownFileType = image.gif; path = nailed.gif; sourceTree = "<group>"; };
005656EC1A6F14D6008A0ED1 /* FrameStore.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = FrameStore.swift; sourceTree = "<group>"; };
005656EE1A6F1C26008A0ED1 /* GIFImageView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = GIFImageView.swift; sourceTree = "<group>"; };
007E08431BD95E6200883D0C /* ArrayExtension.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ArrayExtension.swift; sourceTree = "<group>"; };
007E08431BD95E6200883D0C /* Array.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Array.swift; sourceTree = "<group>"; };
00978B6B1D9C6D2A00A6575F /* Animator.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Animator.swift; sourceTree = "<group>"; };
00978B6D1D9FA99D00A6575F /* AnimatorDelegate.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AnimatorDelegate.swift; sourceTree = "<group>"; };
009BD1361BBC7F6500FC982B /* GifuTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = GifuTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; };
009BD1381BBC7F6500FC982B /* GifuTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = GifuTests.swift; sourceTree = "<group>"; };
009BD13A1BBC7F6500FC982B /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
009BD1431BBC93C800FC982B /* CGSizeExtension.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CGSizeExtension.swift; sourceTree = "<group>"; };
009BD1431BBC93C800FC982B /* CGSize.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CGSize.swift; sourceTree = "<group>"; };
00B8C73E1A364DA400C188E7 /* Gifu.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Gifu.framework; sourceTree = BUILT_PRODUCTS_DIR; };
00B8C7421A364DA400C188E7 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; name = Info.plist; path = ../Source/Info.plist; sourceTree = "<group>"; };
00B8C7421A364DA400C188E7 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
00B8C75C1A364DCE00C188E7 /* ImageSourceHelpers.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ImageSourceHelpers.swift; sourceTree = "<group>"; };
00B8C7951A3650EE00C188E7 /* Gifu.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Gifu.h; sourceTree = "<group>"; };
00BF42CB1D99A1DC00C6F28D /* GIFAnimatable.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = GIFAnimatable.swift; sourceTree = "<group>"; };
EAF49C7E1A3A4DE000B395DF /* UIImageExtension.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = UIImageExtension.swift; sourceTree = "<group>"; };
EAF49C7E1A3A4DE000B395DF /* UIImage.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = UIImage.swift; sourceTree = "<group>"; };
EAF49CB01A3B6EEB00B395DF /* AnimatedFrame.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AnimatedFrame.swift; sourceTree = "<group>"; };
/* End PBXFileReference section */
@ -80,17 +78,17 @@
0036ABB61BBD1D0B00C6CC3D /* mugen.gif */,
0036ABB81BBD1D1400C6CC3D /* nailed.gif */,
);
name = Images;
path = Images;
sourceTree = "<group>";
};
007E08401BD95BE900883D0C /* Extensions */ = {
isa = PBXGroup;
children = (
009BD1431BBC93C800FC982B /* CGSizeExtension.swift */,
EAF49C7E1A3A4DE000B395DF /* UIImageExtension.swift */,
007E08431BD95E6200883D0C /* ArrayExtension.swift */,
007E08431BD95E6200883D0C /* Array.swift */,
009BD1431BBC93C800FC982B /* CGSize.swift */,
EAF49C7E1A3A4DE000B395DF /* UIImage.swift */,
);
name = Extensions;
path = Extensions;
sourceTree = "<group>";
};
007E08411BD95C0200883D0C /* Helpers */ = {
@ -98,7 +96,7 @@
children = (
00B8C75C1A364DCE00C188E7 /* ImageSourceHelpers.swift */,
);
name = Helpers;
path = Helpers;
sourceTree = "<group>";
};
007E08421BD95C6100883D0C /* Classes */ = {
@ -109,17 +107,16 @@
005656EC1A6F14D6008A0ED1 /* FrameStore.swift */,
00BF42CB1D99A1DC00C6F28D /* GIFAnimatable.swift */,
005656EE1A6F1C26008A0ED1 /* GIFImageView.swift */,
00978B6D1D9FA99D00A6575F /* AnimatorDelegate.swift */,
);
name = Classes;
path = Classes;
sourceTree = "<group>";
};
009BD1371BBC7F6500FC982B /* GifuTests */ = {
isa = PBXGroup;
children = (
0036ABBA1BBD1D1700C6CC3D /* Images */,
009BD1381BBC7F6500FC982B /* GifuTests.swift */,
009BD13A1BBC7F6500FC982B /* Info.plist */,
0036ABBA1BBD1D1700C6CC3D /* Images */,
);
path = GifuTests;
sourceTree = "<group>";
@ -127,10 +124,10 @@
00B8C7341A364DA400C188E7 = {
isa = PBXGroup;
children = (
00B8C75A1A364DBE00C188E7 /* Source */,
00B8C7411A364DA400C188E7 /* Supporting Files */,
009BD1371BBC7F6500FC982B /* GifuTests */,
00B8C73F1A364DA400C188E7 /* Products */,
00B8C75A1A364DBE00C188E7 /* Source */,
00B8C7411A364DA400C188E7 /* Supporting Files */,
);
sourceTree = "<group>";
};
@ -148,16 +145,15 @@
children = (
00B8C7421A364DA400C188E7 /* Info.plist */,
);
name = "Supporting Files";
path = Source;
path = "Supporting Files";
sourceTree = "<group>";
};
00B8C75A1A364DBE00C188E7 /* Source */ = {
isa = PBXGroup;
children = (
007E08421BD95C6100883D0C /* Classes */,
007E08411BD95C0200883D0C /* Helpers */,
007E08401BD95BE900883D0C /* Extensions */,
007E08411BD95C0200883D0C /* Helpers */,
00B8C7951A3650EE00C188E7 /* Gifu.h */,
);
path = Source;
@ -303,15 +299,14 @@
buildActionMask = 2147483647;
files = (
005656EF1A6F1C26008A0ED1 /* GIFImageView.swift in Sources */,
00978B6E1D9FA99D00A6575F /* AnimatorDelegate.swift in Sources */,
00BF42CC1D99A1DC00C6F28D /* GIFAnimatable.swift in Sources */,
005656ED1A6F14D6008A0ED1 /* FrameStore.swift in Sources */,
009BD1441BBC93C800FC982B /* CGSizeExtension.swift in Sources */,
009BD1441BBC93C800FC982B /* CGSize.swift in Sources */,
EAF49CB11A3B6EEB00B395DF /* AnimatedFrame.swift in Sources */,
00B8C75F1A364DCE00C188E7 /* ImageSourceHelpers.swift in Sources */,
00978B6C1D9C6D2A00A6575F /* Animator.swift in Sources */,
007E08441BD95E6200883D0C /* ArrayExtension.swift in Sources */,
EAF49C7F1A3A4DE000B395DF /* UIImageExtension.swift in Sources */,
007E08441BD95E6200883D0C /* Array.swift in Sources */,
EAF49C7F1A3A4DE000B395DF /* UIImage.swift in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@ -454,7 +449,7 @@
DYLIB_CURRENT_VERSION = 1;
DYLIB_INSTALL_NAME_BASE = "@rpath";
FRAMEWORK_SEARCH_PATHS = "$(inherited)";
INFOPLIST_FILE = "$(SRCROOT)/Source/Info.plist";
INFOPLIST_FILE = "$(SRCROOT)/Supporting Files/Info.plist";
INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
IPHONEOS_DEPLOYMENT_TARGET = 9.0;
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
@ -476,7 +471,7 @@
DYLIB_CURRENT_VERSION = 1;
DYLIB_INSTALL_NAME_BASE = "@rpath";
FRAMEWORK_SEARCH_PATHS = "$(inherited)";
INFOPLIST_FILE = "$(SRCROOT)/Source/Info.plist";
INFOPLIST_FILE = "$(SRCROOT)/Supporting Files/Info.plist";
INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
IPHONEOS_DEPLOYMENT_TARGET = 9.0;
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";

View File

@ -6,14 +6,20 @@ private let imageData = testImageDataNamed("mugen.gif")
private let staticImage = UIImage(data: imageData)!
private let preloadFrameCount = 20
class DummyAnimatorDelegate: AnimatorDelegate {
func animatorHasNewFrame() { }
class DummyAnimatable: GIFAnimatable {
init() {}
var animator: Animator? = nil
var image: UIImage? = nil
var layer = CALayer()
var frame: CGRect = .zero
var contentMode: UIViewContentMode = .scaleToFill
func animatorHasNewFrame() {}
}
class GifuTests: XCTestCase {
var animator: Animator!
var originalFrameCount: Int!
let delegate = DummyAnimatorDelegate()
let delegate = DummyAnimatable()
override func setUp() {
super.setUp()

View File

Before

Width:  |  Height:  |  Size: 933 KiB

After

Width:  |  Height:  |  Size: 933 KiB

View File

Before

Width:  |  Height:  |  Size: 11 MiB

After

Width:  |  Height:  |  Size: 11 MiB

View File

@ -1,4 +0,0 @@
/// The protocol that an animator delegate needs to conform to.
public protocol AnimatorDelegate: class {
func animatorHasNewFrame()
}

View File

@ -22,7 +22,7 @@ struct AnimatedFrame {
///
/// - parameter image: An optional `UIImage` instance to be assigned to the new frame.
/// - returns: An `AnimatedFrame` instance.
func animatedFrame(with newImage: UIImage?) -> AnimatedFrame {
func makeAnimatedFrame(with newImage: UIImage?) -> AnimatedFrame {
return AnimatedFrame(image: newImage, duration: duration)
}
}

View File

@ -1,12 +1,11 @@
/// Handles the GIF animation logic.
/// Responsible for parsing GIF data and decoding the individual frames.
public class Animator {
/// Number of frame to buffer.
public var frameBufferCount = 50
var frameBufferCount = 50
/// Specifies whether GIF frames should be resized.
public var shouldResizeFrames = false
var shouldResizeFrames = false
/// Responsible for loading individual frames and resizing them if necessary.
var frameStore: FrameStore?
@ -15,7 +14,7 @@ public class Animator {
private var displayLinkInitialized: Bool = false
/// A delegate responsible for displaying the GIF frames.
private weak var delegate: AnimatorDelegate!
private weak var delegate: GIFAnimatable!
/// Responsible for starting and stopping the animation.
private lazy var displayLink: CADisplayLink = { [unowned self] in
@ -35,12 +34,12 @@ public class Animator {
return frameStore?.frameCount ?? 0
}
/// Instantiates a new animator object with a delegate view.
/// Creates a new animator with a delegate.
///
/// - parameter view: A view object that implements the `GIFAnimatable` protocol.
///
/// - returns: A new animator instance.
public init(withDelegate delegate: AnimatorDelegate) {
public init(withDelegate delegate: GIFAnimatable) {
self.delegate = delegate
}
@ -131,7 +130,7 @@ public class Animator {
/// Gets the current image from the frame store.
///
/// - returns: An optional frame image to display.
public func imageToDisplay() -> UIImage? {
func activeFrame() -> UIImage? {
return frameStore?.currentFrameImage
}
}
@ -142,7 +141,7 @@ fileprivate class DisplayLinkProxy {
/// The target animator.
private weak var target: Animator?
/// Init with target animator.
/// Create a new proxy object with a target animator.
///
/// - parameter target: An animator instance.
///

View File

@ -67,7 +67,7 @@ class FrameStore {
return imageSource.isAnimatedGIF
}
/// Initializes an animator instance from raw GIF image data and an `Animatable` delegate.
/// Creates an animator instance from raw GIF image data and an `Animatable` delegate.
///
/// - parameter data: The raw GIF image data.
/// - parameter delegate: An `Animatable` delegate.
@ -159,7 +159,7 @@ private extension FrameStore {
preloadIndexes(withStartingIndex: currentFrameIndex).forEach { index in
let currentAnimatedFrame = animatedFrames[index]
if !currentAnimatedFrame.isPlaceholder { return }
animatedFrames[index] = currentAnimatedFrame.animatedFrame(with: loadFrame(at: index))
animatedFrames[index] = currentAnimatedFrame.makeAnimatedFrame(with: loadFrame(at: index))
}
}
@ -177,7 +177,7 @@ private extension FrameStore {
/// Increments the `currentFrameIndex` property.
func incrementCurrentFrameIndex() {
currentFrameIndex = increment(index: currentFrameIndex)
currentFrameIndex = increment(frameIndex: currentFrameIndex)
}
/// Increments a given frame index, taking into account the `frameCount` and looping when necessary.
@ -185,8 +185,8 @@ private extension FrameStore {
/// - parameter index: The `Int` value to increment.
/// - parameter byValue: The `Int` value to increment with.
/// - returns: A new `Int` value.
func increment(index: Int, by value: Int = 1) -> Int {
return (index + value) % frameCount
func increment(frameIndex: Int, by value: Int = 1) -> Int {
return (frameIndex + value) % frameCount
}
/// Returns the indexes of the frames to preload based on a starting frame index.
@ -194,8 +194,8 @@ private extension FrameStore {
/// - parameter index: Starting index.
/// - returns: An array of indexes to preload.
func preloadIndexes(withStartingIndex index: Int) -> [Int] {
let nextIndex = increment(index: index)
let lastIndex = increment(index: index, by: bufferFrameCount)
let nextIndex = increment(frameIndex: index)
let lastIndex = increment(frameIndex: index, by: bufferFrameCount)
if lastIndex >= nextIndex {
return [Int](nextIndex...lastIndex)
@ -213,7 +213,7 @@ private extension FrameStore {
animatedFrames += [AnimatedFrame(image: .none, duration: frameDuration)]
if index > bufferFrameCount { return }
animatedFrames[index] = animatedFrames[index].animatedFrame(with: loadFrame(at: index))
animatedFrames[index] = animatedFrames[index].makeAnimatedFrame(with: loadFrame(at: index))
}
}

View File

@ -1,5 +1,5 @@
/// The protocol that view classes need to conform to to enable animated GIF support.
public protocol GIFAnimatable: class, AnimatorDelegate, CALayerDelegate {
public protocol GIFAnimatable: class {
/// Responsible for managing the animation frames.
var animator: Animator? { get set }
@ -15,15 +15,8 @@ public protocol GIFAnimatable: class, AnimatorDelegate, CALayerDelegate {
/// Content mode used for resizing the frames.
var contentMode: UIViewContentMode { get set }
/// Implement this method and call `updateImageIfNeeded` from within it in your conforming class.
///
/// - parameter layer:
func display(_ layer: CALayer)
/// Needs to be called whenever the conforming class needs to check if it needs to update the current frame being displayed.
func updateImageIfNeeded()
}
extension GIFAnimatable {
/// Returns the intrinsic content size based on the size of the image.
public var intrinsicContentSize: CGSize {
@ -79,7 +72,12 @@ extension GIFAnimatable {
/// Updates the image with a new frame if necessary.
public func updateImageIfNeeded() {
image = animator?.imageToDisplay() ?? image
image = animator?.activeFrame() ?? image
}
/// Returns the active frame if available.
public func activeFrame() -> UIImage? {
return animator?.activeFrame()
}
}

View File

@ -0,0 +1,17 @@
import UIKit
/// Example class that conforms to `GIFAnimatable`. Uses default values for the animator frame buffer count and resize behavior. You can either use it directly in your code or use it as a blueprint for your own subclass.
public class GIFImageView: UIImageView, GIFAnimatable {
/// A lazy animator.
public lazy var animator: Animator? = {
return Animator(withDelegate: self)
}()
/// Layer delegate method called periodically by the layer. **Should not** be called manually.
///
/// - parameter layer: The delegated layer.
override public func display(_ layer: CALayer) {
updateImageIfNeeded()
}
}

View File

@ -26,7 +26,7 @@ extension CGSize {
///
/// - parameter size: The contraining size.
/// - returns: size A new size that fills the contraining size keeping the same aspect ratio.
func filling(size: CGSize) -> CGSize {
func filling(_ size: CGSize) -> CGSize {
let aspectWidth = round(aspectRatio * size.height)
let aspectHeight = round(size.width / aspectRatio)

View File

@ -27,7 +27,7 @@ extension UIImage {
/// - parameter size: The constraining size of the image.
/// - returns: A new resized image instance.
func filling(size: CGSize) -> UIImage {
let newSize = size.filling(size: size)
let newSize = size.filling(size)
return resized(to: newSize)
}

View File

@ -1,16 +0,0 @@
import UIKit
/// Example class that conforms to `GIFAnimatable`. Uses default values for the animator frame buffer count and resize behavior.
public class GIFImageView: UIImageView, GIFAnimatable {
public var animator: Animator?
required public init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
animator = Animator(withDelegate: self)
}
override public func display(_ layer: CALayer) {
updateImageIfNeeded()
}
}

View File

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