Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Migrate to Swift 3.1 #11

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
44 changes: 24 additions & 20 deletions YLGIFImage-Swift/YLGIFImage.swift
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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
Expand All @@ -42,15 +42,15 @@ class YLGIFImage : UIImage {
for i in 0..<numOfFrames {
// get frame duration
let frameDuration = YLGIFImage.getCGImageSourceGifFrameDelay(cgImageSource, index: UInt(i))
self.frameDurations.append(NSNumber(double: frameDuration))
self.frameDurations.append(NSNumber(value: frameDuration as Double))
self.totalDuration += frameDuration

//Log("dura = \(frameDuration)")

if i < Int(YLGIFImage.prefetchNum) {
// get frame
let cgimage = CGImageSourceCreateImageAtIndex(cgImageSource, i, nil)
let image: UIImage = UIImage(CGImage: cgimage!)
let image: UIImage = UIImage(cgImage: cgimage!)
self.frameImages.append(image)
//Log("\(i): frame = \(image)")
} else {
Expand All @@ -60,11 +60,11 @@ class YLGIFImage : UIImage {
//Log("\(self.frameImages.count)")
}

private lazy var readFrameQueue:dispatch_queue_t = dispatch_queue_create("com.ronnie.gifreadframe", DISPATCH_QUEUE_SERIAL)
fileprivate lazy var readFrameQueue:DispatchQueue = DispatchQueue(label: "com.ronnie.gifreadframe", attributes: [])

private var _scale:CGFloat = 1.0
private var _cgImgSource:CGImageSource? = nil
var totalDuration: NSTimeInterval = 0.0
fileprivate var _scale:CGFloat = 1.0
fileprivate var _cgImgSource:CGImageSource? = nil
var totalDuration: TimeInterval = 0.0
var frameDurations = [AnyObject]()
var loopCount: UInt = 1
var frameImages:[AnyObject] = [AnyObject]()
Expand All @@ -77,29 +77,29 @@ class YLGIFImage : UIImage {
return YLGIFGlobalSetting.prefetchNumber
}

class func setPrefetchNum(number:UInt) {
class func setPrefetchNum(_ number:UInt) {
YLGIFGlobalSetting.prefetchNumber = number
}

convenience init?(named name: String!) {
guard let path = NSBundle.mainBundle().pathForResource(name, ofType: nil)
guard let path = Bundle.main.path(forResource: name, ofType: nil)
else { return nil }
guard let data = NSData(contentsOfURL:NSURL.fileURLWithPath(path))
guard let data = try? Data(contentsOf: URL(fileURLWithPath: path))
else { return nil }
self.init(data: data)
}

convenience override init?(contentsOfFile path: String) {
let data = NSData(contentsOfURL: NSURL(string: path)!)
let data = try? Data(contentsOf: URL(string: path)!)
self.init(data: data!)
}

convenience override init?(data: NSData) {
convenience override init?(data: Data) {
self.init(data: data, scale: 1.0)
}

override init?(data: NSData, scale: CGFloat) {
let cgImgSource = CGImageSourceCreateWithData(data, nil)
override init?(data: Data, scale: CGFloat) {
let cgImgSource = CGImageSourceCreateWithData(data as CFData, nil)
if YLGIFImage.isCGImageSourceContainAnimatedGIF(cgImgSource) {
super.init()
createSelf(cgImgSource, scale: scale)
Expand All @@ -116,7 +116,11 @@ class YLGIFImage : UIImage {
fatalError("init(imageLiteral name:) has not been implemented")
}

func getFrame(index: UInt) -> 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
}
Expand All @@ -129,14 +133,14 @@ 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!)
}
}
}
}

return image
}
}
}
56 changes: 29 additions & 27 deletions YLGIFImage-Swift/YLImageView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -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! {
Expand Down Expand Up @@ -73,62 +73,64 @@ 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()
}
}

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)
var frameDura = animatedImg.frameDurations[self.currentFrameIndex] as! NSNumber
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
}
Expand All @@ -144,4 +146,4 @@ class YLImageView : UIImageView {
self.stopAnimating()
}
}
}
}
23 changes: 23 additions & 0 deletions YLGIFImageSwiftDemo/YLGIFImageSwiftDemo.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -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 */; };
Expand All @@ -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 = "<group>"; };
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 = "<group>"; };
Expand All @@ -52,6 +54,7 @@
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
422B2CD51EAFD688007D6817 /* QuartzCore.framework in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
};
Expand All @@ -65,13 +68,22 @@
/* End PBXFrameworksBuildPhase section */

/* Begin PBXGroup section */
422B2CD31EAFD687007D6817 /* Frameworks */ = {
isa = PBXGroup;
children = (
422B2CD41EAFD688007D6817 /* QuartzCore.framework */,
);
name = Frameworks;
sourceTree = "<group>";
};
4E8046B119447FB6007EFB50 = {
isa = PBXGroup;
children = (
4E8046DC19447FCC007EFB50 /* Classes */,
4E8046BC19447FB6007EFB50 /* YLGIFImageSwiftDemo */,
4E8046CF19447FB6007EFB50 /* YLGIFImageSwiftDemoTests */,
4E8046BB19447FB6007EFB50 /* Products */,
422B2CD31EAFD687007D6817 /* Frameworks */,
);
sourceTree = "<group>";
};
Expand Down Expand Up @@ -184,9 +196,12 @@
TargetAttributes = {
4E8046B919447FB6007EFB50 = {
CreatedOnToolsVersion = 6.0;
DevelopmentTeam = 6X8EXGXZW8;
LastSwiftMigration = 0830;
};
4E8046CB19447FB6007EFB50 = {
CreatedOnToolsVersion = 6.0;
LastSwiftMigration = 0830;
TestTargetID = 4E8046B919447FB6007EFB50;
};
};
Expand Down Expand Up @@ -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;
};
Expand All @@ -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;
};
Expand All @@ -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;
Expand All @@ -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;
Expand Down
Loading