From b5c553bba242d72779b6beeead67e82a2fe33c42 Mon Sep 17 00:00:00 2001 From: Reda Lemeden Date: Sat, 1 Oct 2016 13:41:22 +0200 Subject: [PATCH] Reorganize project using Synx --- Demo/Demo.xcodeproj/project.pbxproj | 35 ++++++----- .../classes => Source}/AppDelegate.swift | 0 .../AppIcon.appiconset/Contents.json | 0 .../AppIcon.appiconset/New icon-60@2x.png | Bin .../New icon-Small-40@2x.png | Bin .../AppIcon.appiconset/New icon-Small@2x.png | Bin .../Images.xcassets/Contents.json | 0 Demo/{demo => Source}/Main.storyboard | 0 .../Supporting Files}/Default-568h@2x.png | Bin .../Supporting Files}/Info.plist | 0 .../Supporting Files}/earth.gif | Bin .../classes => Source}/ViewController.swift | 4 +- Gifu.xcodeproj/project.pbxproj | 57 ++++++++---------- GifuTests/GifuTests.swift | 12 +++- {Demo/GIFs => GifuTests/Images}/mugen.gif | Bin {Demo/GIFs => GifuTests/Images}/nailed.gif | Bin Source/AnimatorDelegate.swift | 4 -- Source/{ => Classes}/AnimatedFrame.swift | 2 +- Source/{ => Classes}/Animator.swift | 17 +++--- Source/{ => Classes}/FrameStore.swift | 16 ++--- Source/{ => Classes}/GIFAnimatable.swift | 22 +++---- Source/Classes/GIFImageView.swift | 17 ++++++ .../Array.swift} | 0 .../CGSize.swift} | 2 +- .../UIImage.swift} | 2 +- Source/GIFImageView.swift | 16 ----- Source/{ => Helpers}/ImageSourceHelpers.swift | 0 {Source => Supporting Files}/Info.plist | 2 +- 28 files changed, 101 insertions(+), 107 deletions(-) rename Demo/{demo/classes => Source}/AppDelegate.swift (100%) rename Demo/{demo => Source}/Images.xcassets/AppIcon.appiconset/Contents.json (100%) rename Demo/{demo => Source}/Images.xcassets/AppIcon.appiconset/New icon-60@2x.png (100%) rename Demo/{demo => Source}/Images.xcassets/AppIcon.appiconset/New icon-Small-40@2x.png (100%) rename Demo/{demo => Source}/Images.xcassets/AppIcon.appiconset/New icon-Small@2x.png (100%) rename Demo/{demo => Source}/Images.xcassets/Contents.json (100%) rename Demo/{demo => Source}/Main.storyboard (100%) rename Demo/{ => Source/Supporting Files}/Default-568h@2x.png (100%) rename Demo/{demo => Source/Supporting Files}/Info.plist (100%) rename Demo/{GIFs => Source/Supporting Files}/earth.gif (100%) rename Demo/{demo/classes => Source}/ViewController.swift (100%) rename {Demo/GIFs => GifuTests/Images}/mugen.gif (100%) rename {Demo/GIFs => GifuTests/Images}/nailed.gif (100%) delete mode 100644 Source/AnimatorDelegate.swift rename Source/{ => Classes}/AnimatedFrame.swift (92%) rename Source/{ => Classes}/Animator.swift (92%) rename Source/{ => Classes}/FrameStore.swift (92%) rename Source/{ => Classes}/GIFAnimatable.swift (80%) create mode 100644 Source/Classes/GIFImageView.swift rename Source/{ArrayExtension.swift => Extensions/Array.swift} (100%) rename Source/{CGSizeExtension.swift => Extensions/CGSize.swift} (96%) rename Source/{UIImageExtension.swift => Extensions/UIImage.swift} (97%) delete mode 100644 Source/GIFImageView.swift rename Source/{ => Helpers}/ImageSourceHelpers.swift (100%) rename {Source => Supporting Files}/Info.plist (97%) diff --git a/Demo/Demo.xcodeproj/project.pbxproj b/Demo/Demo.xcodeproj/project.pbxproj index bbec3ac..4f85854 100755 --- a/Demo/Demo.xcodeproj/project.pbxproj +++ b/Demo/Demo.xcodeproj/project.pbxproj @@ -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 = ""; }; 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 = ""; }; - 002A1BFB1D1624D0005ABBD0 /* mugen.gif */ = {isa = PBXFileReference; lastKnownFileType = image.gif; name = mugen.gif; path = ../GIFs/mugen.gif; sourceTree = ""; }; - 007380221B279644008DAD5C /* Default-568h@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "Default-568h@2x.png"; path = "../Default-568h@2x.png"; sourceTree = ""; }; + 002A1BFB1D1624D0005ABBD0 /* mugen.gif */ = {isa = PBXFileReference; lastKnownFileType = image.gif; name = mugen.gif; path = ../../../GifuTests/Images/mugen.gif; sourceTree = ""; }; + 007380221B279644008DAD5C /* Default-568h@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "Default-568h@2x.png"; sourceTree = ""; }; 9D25870519BCCB0F00A55A18 /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 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 = ""; }; - 9D98823E19BC69CA00B790C6 /* ViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = ViewController.swift; path = classes/ViewController.swift; sourceTree = ""; }; + 9D98823C19BC69CA00B790C6 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; + 9D98823E19BC69CA00B790C6 /* ViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ViewController.swift; sourceTree = ""; }; 9D98824319BC69CA00B790C6 /* Images.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Images.xcassets; sourceTree = ""; }; 9D98825919BC69F600B790C6 /* Main.storyboard */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.storyboard; path = Main.storyboard; sourceTree = ""; }; /* End PBXFileReference section */ @@ -53,9 +53,9 @@ 9D98822E19BC69CA00B790C6 = { isa = PBXGroup; children = ( - 9D98823919BC69CA00B790C6 /* Source */, - 9D98823819BC69CA00B790C6 /* Products */, 002A1BF81D161D32005ABBD0 /* Frameworks */, + 9D98823819BC69CA00B790C6 /* Products */, + 9D98823919BC69CA00B790C6 /* Source */, ); sourceTree = ""; }; @@ -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 = ""; }; 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 = ""; }; /* 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; diff --git a/Demo/demo/classes/AppDelegate.swift b/Demo/Source/AppDelegate.swift similarity index 100% rename from Demo/demo/classes/AppDelegate.swift rename to Demo/Source/AppDelegate.swift diff --git a/Demo/demo/Images.xcassets/AppIcon.appiconset/Contents.json b/Demo/Source/Images.xcassets/AppIcon.appiconset/Contents.json similarity index 100% rename from Demo/demo/Images.xcassets/AppIcon.appiconset/Contents.json rename to Demo/Source/Images.xcassets/AppIcon.appiconset/Contents.json diff --git a/Demo/demo/Images.xcassets/AppIcon.appiconset/New icon-60@2x.png b/Demo/Source/Images.xcassets/AppIcon.appiconset/New icon-60@2x.png similarity index 100% rename from Demo/demo/Images.xcassets/AppIcon.appiconset/New icon-60@2x.png rename to Demo/Source/Images.xcassets/AppIcon.appiconset/New icon-60@2x.png diff --git a/Demo/demo/Images.xcassets/AppIcon.appiconset/New icon-Small-40@2x.png b/Demo/Source/Images.xcassets/AppIcon.appiconset/New icon-Small-40@2x.png similarity index 100% rename from Demo/demo/Images.xcassets/AppIcon.appiconset/New icon-Small-40@2x.png rename to Demo/Source/Images.xcassets/AppIcon.appiconset/New icon-Small-40@2x.png diff --git a/Demo/demo/Images.xcassets/AppIcon.appiconset/New icon-Small@2x.png b/Demo/Source/Images.xcassets/AppIcon.appiconset/New icon-Small@2x.png similarity index 100% rename from Demo/demo/Images.xcassets/AppIcon.appiconset/New icon-Small@2x.png rename to Demo/Source/Images.xcassets/AppIcon.appiconset/New icon-Small@2x.png diff --git a/Demo/demo/Images.xcassets/Contents.json b/Demo/Source/Images.xcassets/Contents.json similarity index 100% rename from Demo/demo/Images.xcassets/Contents.json rename to Demo/Source/Images.xcassets/Contents.json diff --git a/Demo/demo/Main.storyboard b/Demo/Source/Main.storyboard similarity index 100% rename from Demo/demo/Main.storyboard rename to Demo/Source/Main.storyboard diff --git a/Demo/Default-568h@2x.png b/Demo/Source/Supporting Files/Default-568h@2x.png similarity index 100% rename from Demo/Default-568h@2x.png rename to Demo/Source/Supporting Files/Default-568h@2x.png diff --git a/Demo/demo/Info.plist b/Demo/Source/Supporting Files/Info.plist similarity index 100% rename from Demo/demo/Info.plist rename to Demo/Source/Supporting Files/Info.plist diff --git a/Demo/GIFs/earth.gif b/Demo/Source/Supporting Files/earth.gif similarity index 100% rename from Demo/GIFs/earth.gif rename to Demo/Source/Supporting Files/earth.gif diff --git a/Demo/demo/classes/ViewController.swift b/Demo/Source/ViewController.swift similarity index 100% rename from Demo/demo/classes/ViewController.swift rename to Demo/Source/ViewController.swift index 5bf0f2c..35da1c2 100755 --- a/Demo/demo/classes/ViewController.swift +++ b/Demo/Source/ViewController.swift @@ -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) { } } diff --git a/Gifu.xcodeproj/project.pbxproj b/Gifu.xcodeproj/project.pbxproj index e836684..a48e8ea 100644 --- a/Gifu.xcodeproj/project.pbxproj +++ b/Gifu.xcodeproj/project.pbxproj @@ -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 = ""; }; + 0036ABB81BBD1D1400C6CC3D /* nailed.gif */ = {isa = PBXFileReference; lastKnownFileType = image.gif; path = nailed.gif; sourceTree = ""; }; 005656EC1A6F14D6008A0ED1 /* FrameStore.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = FrameStore.swift; sourceTree = ""; }; 005656EE1A6F1C26008A0ED1 /* GIFImageView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = GIFImageView.swift; sourceTree = ""; }; - 007E08431BD95E6200883D0C /* ArrayExtension.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ArrayExtension.swift; sourceTree = ""; }; + 007E08431BD95E6200883D0C /* Array.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Array.swift; sourceTree = ""; }; 00978B6B1D9C6D2A00A6575F /* Animator.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Animator.swift; sourceTree = ""; }; - 00978B6D1D9FA99D00A6575F /* AnimatorDelegate.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AnimatorDelegate.swift; sourceTree = ""; }; 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 = ""; }; 009BD13A1BBC7F6500FC982B /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; - 009BD1431BBC93C800FC982B /* CGSizeExtension.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CGSizeExtension.swift; sourceTree = ""; }; + 009BD1431BBC93C800FC982B /* CGSize.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CGSize.swift; sourceTree = ""; }; 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 = ""; }; + 00B8C7421A364DA400C188E7 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 00B8C75C1A364DCE00C188E7 /* ImageSourceHelpers.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ImageSourceHelpers.swift; sourceTree = ""; }; 00B8C7951A3650EE00C188E7 /* Gifu.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Gifu.h; sourceTree = ""; }; 00BF42CB1D99A1DC00C6F28D /* GIFAnimatable.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = GIFAnimatable.swift; sourceTree = ""; }; - EAF49C7E1A3A4DE000B395DF /* UIImageExtension.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = UIImageExtension.swift; sourceTree = ""; }; + EAF49C7E1A3A4DE000B395DF /* UIImage.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = UIImage.swift; sourceTree = ""; }; EAF49CB01A3B6EEB00B395DF /* AnimatedFrame.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AnimatedFrame.swift; sourceTree = ""; }; /* End PBXFileReference section */ @@ -80,17 +78,17 @@ 0036ABB61BBD1D0B00C6CC3D /* mugen.gif */, 0036ABB81BBD1D1400C6CC3D /* nailed.gif */, ); - name = Images; + path = Images; sourceTree = ""; }; 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 = ""; }; 007E08411BD95C0200883D0C /* Helpers */ = { @@ -98,7 +96,7 @@ children = ( 00B8C75C1A364DCE00C188E7 /* ImageSourceHelpers.swift */, ); - name = Helpers; + path = Helpers; sourceTree = ""; }; 007E08421BD95C6100883D0C /* Classes */ = { @@ -109,17 +107,16 @@ 005656EC1A6F14D6008A0ED1 /* FrameStore.swift */, 00BF42CB1D99A1DC00C6F28D /* GIFAnimatable.swift */, 005656EE1A6F1C26008A0ED1 /* GIFImageView.swift */, - 00978B6D1D9FA99D00A6575F /* AnimatorDelegate.swift */, ); - name = Classes; + path = Classes; sourceTree = ""; }; 009BD1371BBC7F6500FC982B /* GifuTests */ = { isa = PBXGroup; children = ( + 0036ABBA1BBD1D1700C6CC3D /* Images */, 009BD1381BBC7F6500FC982B /* GifuTests.swift */, 009BD13A1BBC7F6500FC982B /* Info.plist */, - 0036ABBA1BBD1D1700C6CC3D /* Images */, ); path = GifuTests; sourceTree = ""; @@ -127,10 +124,10 @@ 00B8C7341A364DA400C188E7 = { isa = PBXGroup; children = ( - 00B8C75A1A364DBE00C188E7 /* Source */, - 00B8C7411A364DA400C188E7 /* Supporting Files */, 009BD1371BBC7F6500FC982B /* GifuTests */, 00B8C73F1A364DA400C188E7 /* Products */, + 00B8C75A1A364DBE00C188E7 /* Source */, + 00B8C7411A364DA400C188E7 /* Supporting Files */, ); sourceTree = ""; }; @@ -148,16 +145,15 @@ children = ( 00B8C7421A364DA400C188E7 /* Info.plist */, ); - name = "Supporting Files"; - path = Source; + path = "Supporting Files"; sourceTree = ""; }; 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"; diff --git a/GifuTests/GifuTests.swift b/GifuTests/GifuTests.swift index 08abad8..4c0ec30 100644 --- a/GifuTests/GifuTests.swift +++ b/GifuTests/GifuTests.swift @@ -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() diff --git a/Demo/GIFs/mugen.gif b/GifuTests/Images/mugen.gif similarity index 100% rename from Demo/GIFs/mugen.gif rename to GifuTests/Images/mugen.gif diff --git a/Demo/GIFs/nailed.gif b/GifuTests/Images/nailed.gif similarity index 100% rename from Demo/GIFs/nailed.gif rename to GifuTests/Images/nailed.gif diff --git a/Source/AnimatorDelegate.swift b/Source/AnimatorDelegate.swift deleted file mode 100644 index f05d294..0000000 --- a/Source/AnimatorDelegate.swift +++ /dev/null @@ -1,4 +0,0 @@ -/// The protocol that an animator delegate needs to conform to. -public protocol AnimatorDelegate: class { - func animatorHasNewFrame() -} diff --git a/Source/AnimatedFrame.swift b/Source/Classes/AnimatedFrame.swift similarity index 92% rename from Source/AnimatedFrame.swift rename to Source/Classes/AnimatedFrame.swift index c235000..19f6743 100644 --- a/Source/AnimatedFrame.swift +++ b/Source/Classes/AnimatedFrame.swift @@ -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) } } diff --git a/Source/Animator.swift b/Source/Classes/Animator.swift similarity index 92% rename from Source/Animator.swift rename to Source/Classes/Animator.swift index 8fa3cdb..1f209ed 100644 --- a/Source/Animator.swift +++ b/Source/Classes/Animator.swift @@ -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. /// diff --git a/Source/FrameStore.swift b/Source/Classes/FrameStore.swift similarity index 92% rename from Source/FrameStore.swift rename to Source/Classes/FrameStore.swift index 99653de..2a70f47 100644 --- a/Source/FrameStore.swift +++ b/Source/Classes/FrameStore.swift @@ -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)) } } diff --git a/Source/GIFAnimatable.swift b/Source/Classes/GIFAnimatable.swift similarity index 80% rename from Source/GIFAnimatable.swift rename to Source/Classes/GIFAnimatable.swift index acf0e37..fb36022 100644 --- a/Source/GIFAnimatable.swift +++ b/Source/Classes/GIFAnimatable.swift @@ -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 { @@ -44,14 +37,14 @@ extension GIFAnimatable { /// 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) { animator?.prepareForAnimation(withGIFNamed: imageName, size: frame.size, contentMode: contentMode) } /// Prepare for animation and start animating immediately. /// - /// - parameter imageData: GIF image data. + /// - parameter imageData: GIF image data. public func prepareForAnimation(withGIFData imageData: Data) { image = UIImage(data: imageData) animator?.prepareForAnimation(withGIFData: imageData, size: frame.size, contentMode: contentMode) @@ -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() } } diff --git a/Source/Classes/GIFImageView.swift b/Source/Classes/GIFImageView.swift new file mode 100644 index 0000000..ea638a5 --- /dev/null +++ b/Source/Classes/GIFImageView.swift @@ -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() + } +} diff --git a/Source/ArrayExtension.swift b/Source/Extensions/Array.swift similarity index 100% rename from Source/ArrayExtension.swift rename to Source/Extensions/Array.swift diff --git a/Source/CGSizeExtension.swift b/Source/Extensions/CGSize.swift similarity index 96% rename from Source/CGSizeExtension.swift rename to Source/Extensions/CGSize.swift index 9a314e6..b936b71 100644 --- a/Source/CGSizeExtension.swift +++ b/Source/Extensions/CGSize.swift @@ -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) diff --git a/Source/UIImageExtension.swift b/Source/Extensions/UIImage.swift similarity index 97% rename from Source/UIImageExtension.swift rename to Source/Extensions/UIImage.swift index d7beb6c..9e81f85 100644 --- a/Source/UIImageExtension.swift +++ b/Source/Extensions/UIImage.swift @@ -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) } diff --git a/Source/GIFImageView.swift b/Source/GIFImageView.swift deleted file mode 100644 index 20995fd..0000000 --- a/Source/GIFImageView.swift +++ /dev/null @@ -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() - } -} diff --git a/Source/ImageSourceHelpers.swift b/Source/Helpers/ImageSourceHelpers.swift similarity index 100% rename from Source/ImageSourceHelpers.swift rename to Source/Helpers/ImageSourceHelpers.swift diff --git a/Source/Info.plist b/Supporting Files/Info.plist similarity index 97% rename from Source/Info.plist rename to Supporting Files/Info.plist index bbf4d51..b355c11 100644 --- a/Source/Info.plist +++ b/Supporting Files/Info.plist @@ -19,7 +19,7 @@ CFBundleSignature ???? CFBundleVersion - 120 + 124 NSPrincipalClass