diff --git a/YLGIFImage-Swift/YLGIFImage.swift b/YLGIFImage-Swift/YLGIFImage.swift index 5ce1c62..54bc970 100644 --- a/YLGIFImage-Swift/YLGIFImage.swift +++ b/YLGIFImage-Swift/YLGIFImage.swift @@ -12,13 +12,13 @@ import MobileCoreServices class YLGIFImage : UIImage { - private class func isCGImageSourceContainAnimatedGIF(cgImageSource: CGImageSource!) -> Bool { + fileprivate class func isCGImageSourceContainAnimatedGIF(_ cgImageSource: CGImageSource!) -> Bool { let isGIF = UTTypeConformsTo(CGImageSourceGetType(cgImageSource)!, kUTTypeGIF) let imgCount = CGImageSourceGetCount(cgImageSource) return isGIF && imgCount > 1 } - private class func getCGImageSourceGifFrameDelay(imageSource: CGImageSourceRef, index: UInt) -> NSTimeInterval { + fileprivate class func getCGImageSourceGifFrameDelay(_ imageSource: CGImageSource, index: UInt) -> TimeInterval { var delay = 0.0 let imgProperties:NSDictionary = CGImageSourceCopyPropertiesAtIndex(imageSource, Int(index), nil)! let gifProperties:NSDictionary? = imgProperties[kCGImagePropertyGIFDictionary as String] as? NSDictionary @@ -31,7 +31,7 @@ class YLGIFImage : UIImage { return delay } - private func createSelf(cgImageSource: CGImageSource!, scale: CGFloat) -> Void { + fileprivate func createSelf(_ cgImageSource: CGImageSource!, scale: CGFloat) -> Void { _cgImgSource = cgImageSource let imageProperties:NSDictionary = CGImageSourceCopyProperties(_cgImgSource!, nil)! let gifProperties: NSDictionary? = imageProperties[kCGImagePropertyGIFDictionary as String] as? NSDictionary @@ -42,7 +42,7 @@ class YLGIFImage : UIImage { for i in 0.. UIImage? { + required convenience init(imageLiteralResourceName name: String) { + fatalError("init(imageLiteralResourceName:) has not been implemented") + } + + func getFrame(_ index: UInt) -> UIImage? { if Int(index) >= self.frameImages.count { return nil } @@ -129,9 +133,9 @@ class YLGIFImage : UIImage { for i in index+1...index+YLGIFImage.prefetchNum { let idx = Int(i)%self.frameImages.count if self.frameImages[idx] is NSNull { - dispatch_async(self.readFrameQueue){ + self.readFrameQueue.async{ let cgImg = CGImageSourceCreateImageAtIndex(self._cgImgSource!, idx, nil) - self.frameImages[idx] = UIImage(CGImage: cgImg!) + self.frameImages[idx] = UIImage(cgImage: cgImg!) } } } @@ -139,4 +143,4 @@ class YLGIFImage : UIImage { return image } -} \ No newline at end of file +} diff --git a/YLGIFImage-Swift/YLImageView.swift b/YLGIFImage-Swift/YLImageView.swift index f918512..02403e0 100644 --- a/YLGIFImage-Swift/YLImageView.swift +++ b/YLGIFImage-Swift/YLImageView.swift @@ -11,35 +11,35 @@ import QuartzCore class YLImageView : UIImageView { - private lazy var displayLink:CADisplayLink = CADisplayLink(target: self, selector: "changeKeyFrame:") - private var accumulator: NSTimeInterval = 0.0 - private var currentFrameIndex: Int = 0 - private var currentFrame: UIImage? = nil - private var loopCountdown: Int = Int.max - private var animatedImage: YLGIFImage? = nil + fileprivate lazy var displayLink:CADisplayLink = CADisplayLink(target: self, selector: #selector(YLImageView.changeKeyFrame(_:))) + fileprivate var accumulator: TimeInterval = 0.0 + fileprivate var currentFrameIndex: Int = 0 + fileprivate var currentFrame: UIImage? = nil + fileprivate var loopCountdown: Int = Int.max + fileprivate var animatedImage: YLGIFImage? = nil required init?(coder aDecoder: NSCoder) { super.init(coder: aDecoder) - self.displayLink.addToRunLoop(NSRunLoop.mainRunLoop(), forMode: NSRunLoopCommonModes) - self.displayLink.paused = true + self.displayLink.add(to: RunLoop.main, forMode: RunLoopMode.commonModes) + self.displayLink.isPaused = true } override init(frame: CGRect) { super.init(frame: frame) - self.displayLink.addToRunLoop(NSRunLoop.mainRunLoop(), forMode: NSRunLoopCommonModes) - self.displayLink.paused = true + self.displayLink.add(to: RunLoop.main, forMode: RunLoopMode.commonModes) + self.displayLink.isPaused = true } override init(image: UIImage?) { super.init(image: image) - self.displayLink.addToRunLoop(NSRunLoop.mainRunLoop(), forMode: NSRunLoopCommonModes) - self.displayLink.paused = true + self.displayLink.add(to: RunLoop.main, forMode: RunLoopMode.commonModes) + self.displayLink.isPaused = true } override init(image: UIImage?, highlightedImage: UIImage!) { super.init(image: image, highlightedImage: highlightedImage) - self.displayLink.addToRunLoop(NSRunLoop.mainRunLoop(), forMode: NSRunLoopCommonModes) - self.displayLink.paused = true + self.displayLink.add(to: RunLoop.main, forMode: RunLoopMode.commonModes) + self.displayLink.isPaused = true } override var image: UIImage! { @@ -73,30 +73,30 @@ class YLImageView : UIImageView { } } - override var highlighted: Bool { + override var isHighlighted: Bool { get{ - return super.highlighted + return super.isHighlighted } set { if (self.animatedImage != nil) { return } else { - return super.highlighted = newValue + return super.isHighlighted = newValue } } } - override func isAnimating() -> Bool { + override var isAnimating : Bool { if (self.animatedImage != nil) { - return !self.displayLink.paused + return !self.displayLink.isPaused } else { - return super.isAnimating() + return super.isAnimating } } override func startAnimating() { if (self.animatedImage != nil) { - self.displayLink.paused = false + self.displayLink.isPaused = false } else { super.startAnimating() } @@ -104,23 +104,25 @@ class YLImageView : UIImageView { override func stopAnimating() { if (self.animatedImage != nil) { - self.displayLink.paused = true + self.displayLink.isPaused = true } else { super.stopAnimating() } } + - override func displayLayer(layer: CALayer) { + override func display(_ layer: CALayer) { if (self.animatedImage != nil) { if let frame = self.currentFrame { - layer.contents = frame.CGImage + layer.contents = frame.cgImage } } else { return } } - func changeKeyFrame(dpLink: CADisplayLink!) -> Void { + + func changeKeyFrame(_ dpLink: CADisplayLink!) -> Void { if let animatedImg = self.animatedImage { if self.currentFrameIndex < animatedImg.frameImages.count { self.accumulator += fmin(1.0, dpLink.duration) @@ -128,7 +130,7 @@ class YLImageView : UIImageView { while self.accumulator >= frameDura.doubleValue { self.accumulator = self.accumulator - frameDura.doubleValue//animatedImg.frameDurations[self.currentFrameIndex] - self.currentFrameIndex++ + self.currentFrameIndex += 1 if Int(self.currentFrameIndex) >= animatedImg.frameImages.count { self.currentFrameIndex = 0 } @@ -144,4 +146,4 @@ class YLImageView : UIImageView { self.stopAnimating() } } -} \ No newline at end of file +} diff --git a/YLGIFImageSwiftDemo/YLGIFImageSwiftDemo.xcodeproj/project.pbxproj b/YLGIFImageSwiftDemo/YLGIFImageSwiftDemo.xcodeproj/project.pbxproj index 0fd0a48..7a61adb 100644 --- a/YLGIFImageSwiftDemo/YLGIFImageSwiftDemo.xcodeproj/project.pbxproj +++ b/YLGIFImageSwiftDemo/YLGIFImageSwiftDemo.xcodeproj/project.pbxproj @@ -7,6 +7,7 @@ objects = { /* Begin PBXBuildFile section */ + 422B2CD51EAFD688007D6817 /* QuartzCore.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 422B2CD41EAFD688007D6817 /* QuartzCore.framework */; }; 4E5096751961B64000D37D33 /* joy.gif in Resources */ = {isa = PBXBuildFile; fileRef = 4E5096741961B64000D37D33 /* joy.gif */; }; 4E8046C019447FB6007EFB50 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4E8046BF19447FB6007EFB50 /* AppDelegate.swift */; }; 4E8046C219447FB6007EFB50 /* ViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4E8046C119447FB6007EFB50 /* ViewController.swift */; }; @@ -31,6 +32,7 @@ /* End PBXContainerItemProxy section */ /* Begin PBXFileReference section */ + 422B2CD41EAFD688007D6817 /* QuartzCore.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = QuartzCore.framework; path = System/Library/Frameworks/QuartzCore.framework; sourceTree = SDKROOT; }; 4E5096741961B64000D37D33 /* joy.gif */ = {isa = PBXFileReference; lastKnownFileType = image.gif; path = joy.gif; sourceTree = ""; }; 4E8046BA19447FB6007EFB50 /* YLGIFImageSwiftDemo.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = YLGIFImageSwiftDemo.app; sourceTree = BUILT_PRODUCTS_DIR; }; 4E8046BE19447FB6007EFB50 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; @@ -52,6 +54,7 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( + 422B2CD51EAFD688007D6817 /* QuartzCore.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -65,6 +68,14 @@ /* End PBXFrameworksBuildPhase section */ /* Begin PBXGroup section */ + 422B2CD31EAFD687007D6817 /* Frameworks */ = { + isa = PBXGroup; + children = ( + 422B2CD41EAFD688007D6817 /* QuartzCore.framework */, + ); + name = Frameworks; + sourceTree = ""; + }; 4E8046B119447FB6007EFB50 = { isa = PBXGroup; children = ( @@ -72,6 +83,7 @@ 4E8046BC19447FB6007EFB50 /* YLGIFImageSwiftDemo */, 4E8046CF19447FB6007EFB50 /* YLGIFImageSwiftDemoTests */, 4E8046BB19447FB6007EFB50 /* Products */, + 422B2CD31EAFD687007D6817 /* Frameworks */, ); sourceTree = ""; }; @@ -184,9 +196,12 @@ TargetAttributes = { 4E8046B919447FB6007EFB50 = { CreatedOnToolsVersion = 6.0; + DevelopmentTeam = 6X8EXGXZW8; + LastSwiftMigration = 0830; }; 4E8046CB19447FB6007EFB50 = { CreatedOnToolsVersion = 6.0; + LastSwiftMigration = 0830; TestTargetID = 4E8046B919447FB6007EFB50; }; }; @@ -359,10 +374,13 @@ buildSettings = { ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; CODE_SIGN_IDENTITY = "iPhone Developer"; + DEVELOPMENT_TEAM = 6X8EXGXZW8; INFOPLIST_FILE = YLGIFImageSwiftDemo/Info.plist; IPHONEOS_DEPLOYMENT_TARGET = 7.0; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; + PRODUCT_BUNDLE_IDENTIFIER = com.sameer.YLGIFImageSwiftDemo; PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_VERSION = 3.0; }; name = Debug; }; @@ -371,10 +389,13 @@ buildSettings = { ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; CODE_SIGN_IDENTITY = "iPhone Developer"; + DEVELOPMENT_TEAM = 6X8EXGXZW8; INFOPLIST_FILE = YLGIFImageSwiftDemo/Info.plist; IPHONEOS_DEPLOYMENT_TARGET = 7.0; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; + PRODUCT_BUNDLE_IDENTIFIER = com.sameer.YLGIFImageSwiftDemo; PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_VERSION = 3.0; }; name = Release; }; @@ -394,6 +415,7 @@ LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; METAL_ENABLE_DEBUG_INFO = YES; PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_VERSION = 3.0; TEST_HOST = "$(BUNDLE_LOADER)"; }; name = Debug; @@ -410,6 +432,7 @@ LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; METAL_ENABLE_DEBUG_INFO = NO; PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_VERSION = 3.0; TEST_HOST = "$(BUNDLE_LOADER)"; }; name = Release; diff --git a/YLGIFImageSwiftDemo/YLGIFImageSwiftDemo/AppDelegate.swift b/YLGIFImageSwiftDemo/YLGIFImageSwiftDemo/AppDelegate.swift index 00c5514..b187390 100644 --- a/YLGIFImageSwiftDemo/YLGIFImageSwiftDemo/AppDelegate.swift +++ b/YLGIFImageSwiftDemo/YLGIFImageSwiftDemo/AppDelegate.swift @@ -14,30 +14,30 @@ class AppDelegate: UIResponder, UIApplicationDelegate { var window: UIWindow? - func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject : AnyObject]?) -> Bool { + func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool { // Override point for customization after application launch. return true } - func applicationWillResignActive(application: UIApplication) { + func applicationWillResignActive(_ application: UIApplication) { // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state. // Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use this method to pause the game. } - func applicationDidEnterBackground(application: UIApplication) { + func applicationDidEnterBackground(_ application: UIApplication) { // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later. // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits. } - func applicationWillEnterForeground(application: UIApplication) { + func applicationWillEnterForeground(_ application: UIApplication) { // Called as part of the transition from the background to the inactive state; here you can undo many of the changes made on entering the background. } - func applicationDidBecomeActive(application: UIApplication) { + func applicationDidBecomeActive(_ application: UIApplication) { // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface. } - func applicationWillTerminate(application: UIApplication) { + func applicationWillTerminate(_ application: UIApplication) { // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:. } diff --git a/YLGIFImageSwiftDemo/YLGIFImageSwiftDemo/Info.plist b/YLGIFImageSwiftDemo/YLGIFImageSwiftDemo/Info.plist index 2a88978..5936a9d 100644 --- a/YLGIFImageSwiftDemo/YLGIFImageSwiftDemo/Info.plist +++ b/YLGIFImageSwiftDemo/YLGIFImageSwiftDemo/Info.plist @@ -7,7 +7,7 @@ CFBundleExecutable ${EXECUTABLE_NAME} CFBundleIdentifier - com.ronnie.${PRODUCT_NAME:rfc1034identifier} + $(PRODUCT_BUNDLE_IDENTIFIER) CFBundleInfoDictionaryVersion 6.0 CFBundleName diff --git a/YLGIFImageSwiftDemo/YLGIFImageSwiftDemo/ViewController.swift b/YLGIFImageSwiftDemo/YLGIFImageSwiftDemo/ViewController.swift index a1ddaf4..f417d8d 100644 --- a/YLGIFImageSwiftDemo/YLGIFImageSwiftDemo/ViewController.swift +++ b/YLGIFImageSwiftDemo/YLGIFImageSwiftDemo/ViewController.swift @@ -20,13 +20,13 @@ class ViewController: UIViewController { YLGIFImage.setPrefetchNum(5) // Do any additional setup after loading the view, typically from a nib. - let path = NSBundle.mainBundle().URLForResource("iwatch", withExtension: "gif")?.absoluteString as String! - imageView.image = YLGIFImage(contentsOfFile: path) + let path = Bundle.main.url(forResource: "iwatch", withExtension: "gif")?.absoluteString as String! + imageView.image = YLGIFImage(contentsOfFile: path!) - if imageView.isAnimating() { - self.button.setTitle("Pause", forState: UIControlState.Normal) + if imageView.isAnimating { + self.button.setTitle("Pause", for: UIControlState()) } else { - self.button.setTitle("Play", forState: UIControlState.Normal) + self.button.setTitle("Play", for: UIControlState()) } } @@ -35,18 +35,18 @@ class ViewController: UIViewController { // Dispose of any resources that can be recreated. } - @IBAction func clicked(button:UIButton) { + @IBAction func clicked(_ button:UIButton) { - if imageView.isAnimating() { + if imageView.isAnimating { imageView.stopAnimating() } else { imageView.startAnimating() } - if imageView.isAnimating() { - self.button.setTitle("Pause", forState: UIControlState.Normal) + if imageView.isAnimating { + self.button.setTitle("Pause", for: UIControlState()) } else { - self.button.setTitle("Play", forState: UIControlState.Normal) + self.button.setTitle("Play", for: UIControlState()) } } diff --git a/YLGIFImageSwiftDemo/YLGIFImageSwiftDemoTests/YLGIFImageSwiftDemoTests.swift b/YLGIFImageSwiftDemo/YLGIFImageSwiftDemoTests/YLGIFImageSwiftDemoTests.swift index 61a204c..0f656dd 100644 --- a/YLGIFImageSwiftDemo/YLGIFImageSwiftDemoTests/YLGIFImageSwiftDemoTests.swift +++ b/YLGIFImageSwiftDemo/YLGIFImageSwiftDemoTests/YLGIFImageSwiftDemoTests.swift @@ -27,7 +27,7 @@ class YLGIFImageSwiftDemoTests: XCTestCase { func testPerformanceExample() { // This is an example of a performance test case. - self.measureBlock() { + self.measure() { // Put the code you want to measure the time of here. } }