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 */ /* End PBXBuildFile section */
/* Begin PBXFileReference 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>"; }; 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>"; }; 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; name = "Default-568h@2x.png"; path = "../Default-568h@2x.png"; 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>"; }; 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; }; 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>"; }; 9D98823C19BC69CA00B790C6 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = "<group>"; };
9D98823E19BC69CA00B790C6 /* ViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = ViewController.swift; path = classes/ViewController.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>"; }; 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>"; }; 9D98825919BC69F600B790C6 /* Main.storyboard */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.storyboard; path = Main.storyboard; sourceTree = "<group>"; };
/* End PBXFileReference section */ /* End PBXFileReference section */
@ -53,9 +53,9 @@
9D98822E19BC69CA00B790C6 = { 9D98822E19BC69CA00B790C6 = {
isa = PBXGroup; isa = PBXGroup;
children = ( children = (
9D98823919BC69CA00B790C6 /* Source */,
9D98823819BC69CA00B790C6 /* Products */,
002A1BF81D161D32005ABBD0 /* Frameworks */, 002A1BF81D161D32005ABBD0 /* Frameworks */,
9D98823819BC69CA00B790C6 /* Products */,
9D98823919BC69CA00B790C6 /* Source */,
); );
sourceTree = "<group>"; sourceTree = "<group>";
}; };
@ -70,25 +70,24 @@
9D98823919BC69CA00B790C6 /* Source */ = { 9D98823919BC69CA00B790C6 /* Source */ = {
isa = PBXGroup; isa = PBXGroup;
children = ( children = (
9D98823C19BC69CA00B790C6 /* AppDelegate.swift */,
9D98823E19BC69CA00B790C6 /* ViewController.swift */,
9D98825919BC69F600B790C6 /* Main.storyboard */,
9D98824319BC69CA00B790C6 /* Images.xcassets */,
9D98823A19BC69CA00B790C6 /* Supporting Files */, 9D98823A19BC69CA00B790C6 /* Supporting Files */,
9D98823C19BC69CA00B790C6 /* AppDelegate.swift */,
9D98824319BC69CA00B790C6 /* Images.xcassets */,
9D98825919BC69F600B790C6 /* Main.storyboard */,
9D98823E19BC69CA00B790C6 /* ViewController.swift */,
); );
name = Source; path = Source;
path = demo;
sourceTree = "<group>"; sourceTree = "<group>";
}; };
9D98823A19BC69CA00B790C6 /* Supporting Files */ = { 9D98823A19BC69CA00B790C6 /* Supporting Files */ = {
isa = PBXGroup; isa = PBXGroup;
children = ( children = (
0009FCE61D16A4AB0038DC85 /* earth.gif */,
002A1BFB1D1624D0005ABBD0 /* mugen.gif */,
007380221B279644008DAD5C /* Default-568h@2x.png */, 007380221B279644008DAD5C /* Default-568h@2x.png */,
9D25870519BCCB0F00A55A18 /* Info.plist */, 9D25870519BCCB0F00A55A18 /* Info.plist */,
0009FCE61D16A4AB0038DC85 /* earth.gif */,
002A1BFB1D1624D0005ABBD0 /* mugen.gif */,
); );
name = "Supporting Files"; path = "Supporting Files";
sourceTree = "<group>"; sourceTree = "<group>";
}; };
/* End PBXGroup section */ /* End PBXGroup section */
@ -259,7 +258,7 @@
buildSettings = { buildSettings = {
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
FRAMEWORK_SEARCH_PATHS = "$(inherited)"; FRAMEWORK_SEARCH_PATHS = "$(inherited)";
INFOPLIST_FILE = demo/Info.plist; INFOPLIST_FILE = "Source/Supporting Files/Info.plist";
IPHONEOS_DEPLOYMENT_TARGET = 9.0; IPHONEOS_DEPLOYMENT_TARGET = 9.0;
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
PRODUCT_BUNDLE_IDENTIFIER = co.kaishin.gifu.demo; PRODUCT_BUNDLE_IDENTIFIER = co.kaishin.gifu.demo;
@ -274,7 +273,7 @@
buildSettings = { buildSettings = {
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
FRAMEWORK_SEARCH_PATHS = "$(inherited)"; FRAMEWORK_SEARCH_PATHS = "$(inherited)";
INFOPLIST_FILE = demo/Info.plist; INFOPLIST_FILE = "Source/Supporting Files/Info.plist";
IPHONEOS_DEPLOYMENT_TARGET = 9.0; IPHONEOS_DEPLOYMENT_TARGET = 9.0;
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
PRODUCT_BUNDLE_IDENTIFIER = co.kaishin.gifu.demo; 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 { class ViewController: UIViewController {
@IBOutlet weak var imageView: GIFImageView! @IBOutlet weak var imageView: GIFImageView!
@IBAction func unwindToRootViewController(segue: UIStoryboardSegue) { }
var currentGIFName: String = "mugen" { var currentGIFName: String = "mugen" {
didSet { didSet {
imageView.animate(withGIFNamed: currentGIFName) imageView.animate(withGIFNamed: currentGIFName)
@ -33,6 +35,4 @@ class ViewController: UIViewController {
override func viewDidAppear(_ animated: Bool) { override func viewDidAppear(_ animated: Bool) {
imageView.animate(withGIFNamed: currentGIFName) 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 */; }; 0036ABB91BBD1D1400C6CC3D /* nailed.gif in Resources */ = {isa = PBXBuildFile; fileRef = 0036ABB81BBD1D1400C6CC3D /* nailed.gif */; };
005656ED1A6F14D6008A0ED1 /* FrameStore.swift in Sources */ = {isa = PBXBuildFile; fileRef = 005656EC1A6F14D6008A0ED1 /* FrameStore.swift */; }; 005656ED1A6F14D6008A0ED1 /* FrameStore.swift in Sources */ = {isa = PBXBuildFile; fileRef = 005656EC1A6F14D6008A0ED1 /* FrameStore.swift */; };
005656EF1A6F1C26008A0ED1 /* GIFImageView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 005656EE1A6F1C26008A0ED1 /* GIFImageView.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 */; }; 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 */; }; 009BD1391BBC7F6500FC982B /* GifuTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 009BD1381BBC7F6500FC982B /* GifuTests.swift */; };
009BD13B1BBC7F6500FC982B /* Gifu.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 00B8C73E1A364DA400C188E7 /* Gifu.framework */; }; 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 */; }; 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, ); }; }; 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 */; }; 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 */; }; EAF49CB11A3B6EEB00B395DF /* AnimatedFrame.swift in Sources */ = {isa = PBXBuildFile; fileRef = EAF49CB01A3B6EEB00B395DF /* AnimatedFrame.swift */; };
/* End PBXBuildFile section */ /* End PBXBuildFile section */
@ -35,23 +34,22 @@
/* End PBXContainerItemProxy section */ /* End PBXContainerItemProxy section */
/* Begin PBXFileReference section */ /* Begin PBXFileReference section */
0036ABB61BBD1D0B00C6CC3D /* mugen.gif */ = {isa = PBXFileReference; lastKnownFileType = image.gif; name = mugen.gif; path = Demo/GIFs/mugen.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; name = nailed.gif; path = Demo/GIFs/nailed.gif; sourceTree = SOURCE_ROOT; }; 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>"; }; 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>"; }; 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>"; }; 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; }; 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>"; }; 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>"; }; 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; }; 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>"; }; 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>"; }; 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>"; }; 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>"; }; EAF49CB01A3B6EEB00B395DF /* AnimatedFrame.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AnimatedFrame.swift; sourceTree = "<group>"; };
/* End PBXFileReference section */ /* End PBXFileReference section */
@ -80,17 +78,17 @@
0036ABB61BBD1D0B00C6CC3D /* mugen.gif */, 0036ABB61BBD1D0B00C6CC3D /* mugen.gif */,
0036ABB81BBD1D1400C6CC3D /* nailed.gif */, 0036ABB81BBD1D1400C6CC3D /* nailed.gif */,
); );
name = Images; path = Images;
sourceTree = "<group>"; sourceTree = "<group>";
}; };
007E08401BD95BE900883D0C /* Extensions */ = { 007E08401BD95BE900883D0C /* Extensions */ = {
isa = PBXGroup; isa = PBXGroup;
children = ( children = (
009BD1431BBC93C800FC982B /* CGSizeExtension.swift */, 007E08431BD95E6200883D0C /* Array.swift */,
EAF49C7E1A3A4DE000B395DF /* UIImageExtension.swift */, 009BD1431BBC93C800FC982B /* CGSize.swift */,
007E08431BD95E6200883D0C /* ArrayExtension.swift */, EAF49C7E1A3A4DE000B395DF /* UIImage.swift */,
); );
name = Extensions; path = Extensions;
sourceTree = "<group>"; sourceTree = "<group>";
}; };
007E08411BD95C0200883D0C /* Helpers */ = { 007E08411BD95C0200883D0C /* Helpers */ = {
@ -98,7 +96,7 @@
children = ( children = (
00B8C75C1A364DCE00C188E7 /* ImageSourceHelpers.swift */, 00B8C75C1A364DCE00C188E7 /* ImageSourceHelpers.swift */,
); );
name = Helpers; path = Helpers;
sourceTree = "<group>"; sourceTree = "<group>";
}; };
007E08421BD95C6100883D0C /* Classes */ = { 007E08421BD95C6100883D0C /* Classes */ = {
@ -109,17 +107,16 @@
005656EC1A6F14D6008A0ED1 /* FrameStore.swift */, 005656EC1A6F14D6008A0ED1 /* FrameStore.swift */,
00BF42CB1D99A1DC00C6F28D /* GIFAnimatable.swift */, 00BF42CB1D99A1DC00C6F28D /* GIFAnimatable.swift */,
005656EE1A6F1C26008A0ED1 /* GIFImageView.swift */, 005656EE1A6F1C26008A0ED1 /* GIFImageView.swift */,
00978B6D1D9FA99D00A6575F /* AnimatorDelegate.swift */,
); );
name = Classes; path = Classes;
sourceTree = "<group>"; sourceTree = "<group>";
}; };
009BD1371BBC7F6500FC982B /* GifuTests */ = { 009BD1371BBC7F6500FC982B /* GifuTests */ = {
isa = PBXGroup; isa = PBXGroup;
children = ( children = (
0036ABBA1BBD1D1700C6CC3D /* Images */,
009BD1381BBC7F6500FC982B /* GifuTests.swift */, 009BD1381BBC7F6500FC982B /* GifuTests.swift */,
009BD13A1BBC7F6500FC982B /* Info.plist */, 009BD13A1BBC7F6500FC982B /* Info.plist */,
0036ABBA1BBD1D1700C6CC3D /* Images */,
); );
path = GifuTests; path = GifuTests;
sourceTree = "<group>"; sourceTree = "<group>";
@ -127,10 +124,10 @@
00B8C7341A364DA400C188E7 = { 00B8C7341A364DA400C188E7 = {
isa = PBXGroup; isa = PBXGroup;
children = ( children = (
00B8C75A1A364DBE00C188E7 /* Source */,
00B8C7411A364DA400C188E7 /* Supporting Files */,
009BD1371BBC7F6500FC982B /* GifuTests */, 009BD1371BBC7F6500FC982B /* GifuTests */,
00B8C73F1A364DA400C188E7 /* Products */, 00B8C73F1A364DA400C188E7 /* Products */,
00B8C75A1A364DBE00C188E7 /* Source */,
00B8C7411A364DA400C188E7 /* Supporting Files */,
); );
sourceTree = "<group>"; sourceTree = "<group>";
}; };
@ -148,16 +145,15 @@
children = ( children = (
00B8C7421A364DA400C188E7 /* Info.plist */, 00B8C7421A364DA400C188E7 /* Info.plist */,
); );
name = "Supporting Files"; path = "Supporting Files";
path = Source;
sourceTree = "<group>"; sourceTree = "<group>";
}; };
00B8C75A1A364DBE00C188E7 /* Source */ = { 00B8C75A1A364DBE00C188E7 /* Source */ = {
isa = PBXGroup; isa = PBXGroup;
children = ( children = (
007E08421BD95C6100883D0C /* Classes */, 007E08421BD95C6100883D0C /* Classes */,
007E08411BD95C0200883D0C /* Helpers */,
007E08401BD95BE900883D0C /* Extensions */, 007E08401BD95BE900883D0C /* Extensions */,
007E08411BD95C0200883D0C /* Helpers */,
00B8C7951A3650EE00C188E7 /* Gifu.h */, 00B8C7951A3650EE00C188E7 /* Gifu.h */,
); );
path = Source; path = Source;
@ -303,15 +299,14 @@
buildActionMask = 2147483647; buildActionMask = 2147483647;
files = ( files = (
005656EF1A6F1C26008A0ED1 /* GIFImageView.swift in Sources */, 005656EF1A6F1C26008A0ED1 /* GIFImageView.swift in Sources */,
00978B6E1D9FA99D00A6575F /* AnimatorDelegate.swift in Sources */,
00BF42CC1D99A1DC00C6F28D /* GIFAnimatable.swift in Sources */, 00BF42CC1D99A1DC00C6F28D /* GIFAnimatable.swift in Sources */,
005656ED1A6F14D6008A0ED1 /* FrameStore.swift in Sources */, 005656ED1A6F14D6008A0ED1 /* FrameStore.swift in Sources */,
009BD1441BBC93C800FC982B /* CGSizeExtension.swift in Sources */, 009BD1441BBC93C800FC982B /* CGSize.swift in Sources */,
EAF49CB11A3B6EEB00B395DF /* AnimatedFrame.swift in Sources */, EAF49CB11A3B6EEB00B395DF /* AnimatedFrame.swift in Sources */,
00B8C75F1A364DCE00C188E7 /* ImageSourceHelpers.swift in Sources */, 00B8C75F1A364DCE00C188E7 /* ImageSourceHelpers.swift in Sources */,
00978B6C1D9C6D2A00A6575F /* Animator.swift in Sources */, 00978B6C1D9C6D2A00A6575F /* Animator.swift in Sources */,
007E08441BD95E6200883D0C /* ArrayExtension.swift in Sources */, 007E08441BD95E6200883D0C /* Array.swift in Sources */,
EAF49C7F1A3A4DE000B395DF /* UIImageExtension.swift in Sources */, EAF49C7F1A3A4DE000B395DF /* UIImage.swift in Sources */,
); );
runOnlyForDeploymentPostprocessing = 0; runOnlyForDeploymentPostprocessing = 0;
}; };
@ -454,7 +449,7 @@
DYLIB_CURRENT_VERSION = 1; DYLIB_CURRENT_VERSION = 1;
DYLIB_INSTALL_NAME_BASE = "@rpath"; DYLIB_INSTALL_NAME_BASE = "@rpath";
FRAMEWORK_SEARCH_PATHS = "$(inherited)"; FRAMEWORK_SEARCH_PATHS = "$(inherited)";
INFOPLIST_FILE = "$(SRCROOT)/Source/Info.plist"; INFOPLIST_FILE = "$(SRCROOT)/Supporting Files/Info.plist";
INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
IPHONEOS_DEPLOYMENT_TARGET = 9.0; IPHONEOS_DEPLOYMENT_TARGET = 9.0;
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
@ -476,7 +471,7 @@
DYLIB_CURRENT_VERSION = 1; DYLIB_CURRENT_VERSION = 1;
DYLIB_INSTALL_NAME_BASE = "@rpath"; DYLIB_INSTALL_NAME_BASE = "@rpath";
FRAMEWORK_SEARCH_PATHS = "$(inherited)"; FRAMEWORK_SEARCH_PATHS = "$(inherited)";
INFOPLIST_FILE = "$(SRCROOT)/Source/Info.plist"; INFOPLIST_FILE = "$(SRCROOT)/Supporting Files/Info.plist";
INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
IPHONEOS_DEPLOYMENT_TARGET = 9.0; IPHONEOS_DEPLOYMENT_TARGET = 9.0;
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; 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 staticImage = UIImage(data: imageData)!
private let preloadFrameCount = 20 private let preloadFrameCount = 20
class DummyAnimatorDelegate: AnimatorDelegate { class DummyAnimatable: GIFAnimatable {
func animatorHasNewFrame() { } 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 { class GifuTests: XCTestCase {
var animator: Animator! var animator: Animator!
var originalFrameCount: Int! var originalFrameCount: Int!
let delegate = DummyAnimatorDelegate() let delegate = DummyAnimatable()
override func setUp() { override func setUp() {
super.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. /// - parameter image: An optional `UIImage` instance to be assigned to the new frame.
/// - returns: An `AnimatedFrame` instance. /// - returns: An `AnimatedFrame` instance.
func animatedFrame(with newImage: UIImage?) -> AnimatedFrame { func makeAnimatedFrame(with newImage: UIImage?) -> AnimatedFrame {
return AnimatedFrame(image: newImage, duration: duration) return AnimatedFrame(image: newImage, duration: duration)
} }
} }

View File

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

View File

@ -67,7 +67,7 @@ class FrameStore {
return imageSource.isAnimatedGIF 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 data: The raw GIF image data.
/// - parameter delegate: An `Animatable` delegate. /// - parameter delegate: An `Animatable` delegate.
@ -159,7 +159,7 @@ private extension FrameStore {
preloadIndexes(withStartingIndex: currentFrameIndex).forEach { index in preloadIndexes(withStartingIndex: currentFrameIndex).forEach { index in
let currentAnimatedFrame = animatedFrames[index] let currentAnimatedFrame = animatedFrames[index]
if !currentAnimatedFrame.isPlaceholder { return } 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. /// Increments the `currentFrameIndex` property.
func incrementCurrentFrameIndex() { func incrementCurrentFrameIndex() {
currentFrameIndex = increment(index: currentFrameIndex) currentFrameIndex = increment(frameIndex: currentFrameIndex)
} }
/// Increments a given frame index, taking into account the `frameCount` and looping when necessary. /// 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 index: The `Int` value to increment.
/// - parameter byValue: The `Int` value to increment with. /// - parameter byValue: The `Int` value to increment with.
/// - returns: A new `Int` value. /// - returns: A new `Int` value.
func increment(index: Int, by value: Int = 1) -> Int { func increment(frameIndex: Int, by value: Int = 1) -> Int {
return (index + value) % frameCount return (frameIndex + value) % frameCount
} }
/// Returns the indexes of the frames to preload based on a starting frame index. /// 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. /// - parameter index: Starting index.
/// - returns: An array of indexes to preload. /// - returns: An array of indexes to preload.
func preloadIndexes(withStartingIndex index: Int) -> [Int] { func preloadIndexes(withStartingIndex index: Int) -> [Int] {
let nextIndex = increment(index: index) let nextIndex = increment(frameIndex: index)
let lastIndex = increment(index: index, by: bufferFrameCount) let lastIndex = increment(frameIndex: index, by: bufferFrameCount)
if lastIndex >= nextIndex { if lastIndex >= nextIndex {
return [Int](nextIndex...lastIndex) return [Int](nextIndex...lastIndex)
@ -213,7 +213,7 @@ private extension FrameStore {
animatedFrames += [AnimatedFrame(image: .none, duration: frameDuration)] animatedFrames += [AnimatedFrame(image: .none, duration: frameDuration)]
if index > bufferFrameCount { return } 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. /// 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. /// Responsible for managing the animation frames.
var animator: Animator? { get set } var animator: Animator? { get set }
@ -15,15 +15,8 @@ public protocol GIFAnimatable: class, AnimatorDelegate, CALayerDelegate {
/// Content mode used for resizing the frames. /// Content mode used for resizing the frames.
var contentMode: UIViewContentMode { get set } 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 { extension GIFAnimatable {
/// Returns the intrinsic content size based on the size of the image. /// Returns the intrinsic content size based on the size of the image.
public var intrinsicContentSize: CGSize { public var intrinsicContentSize: CGSize {
@ -44,14 +37,14 @@ extension GIFAnimatable {
/// Prepares the animator instance for animation. /// Prepares the animator instance for animation.
/// ///
/// - parameter imageName: The file name of the GIF in the main bundle. /// - parameter imageName: The file name of the GIF in the main bundle.
public func prepareForAnimation(withGIFNamed imageName: String) { public func prepareForAnimation(withGIFNamed imageName: String) {
animator?.prepareForAnimation(withGIFNamed: imageName, size: frame.size, contentMode: contentMode) animator?.prepareForAnimation(withGIFNamed: imageName, size: frame.size, contentMode: contentMode)
} }
/// Prepare for animation and start animating immediately. /// Prepare for animation and start animating immediately.
/// ///
/// - parameter imageData: GIF image data. /// - parameter imageData: GIF image data.
public func prepareForAnimation(withGIFData imageData: Data) { public func prepareForAnimation(withGIFData imageData: Data) {
image = UIImage(data: imageData) image = UIImage(data: imageData)
animator?.prepareForAnimation(withGIFData: imageData, size: frame.size, contentMode: contentMode) animator?.prepareForAnimation(withGIFData: imageData, size: frame.size, contentMode: contentMode)
@ -79,7 +72,12 @@ extension GIFAnimatable {
/// Updates the image with a new frame if necessary. /// Updates the image with a new frame if necessary.
public func updateImageIfNeeded() { 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. /// - parameter size: The contraining size.
/// - returns: size A new size that fills the contraining size keeping the same aspect ratio. /// - 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 aspectWidth = round(aspectRatio * size.height)
let aspectHeight = round(size.width / aspectRatio) let aspectHeight = round(size.width / aspectRatio)

View File

@ -27,7 +27,7 @@ extension UIImage {
/// - parameter size: The constraining size of the image. /// - parameter size: The constraining size of the image.
/// - returns: A new resized image instance. /// - returns: A new resized image instance.
func filling(size: CGSize) -> UIImage { func filling(size: CGSize) -> UIImage {
let newSize = size.filling(size: size) let newSize = size.filling(size)
return resized(to: newSize) 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> <key>CFBundleSignature</key>
<string>????</string> <string>????</string>
<key>CFBundleVersion</key> <key>CFBundleVersion</key>
<string>120</string> <string>124</string>
<key>NSPrincipalClass</key> <key>NSPrincipalClass</key>
<string></string> <string></string>
</dict> </dict>