Skip to content
This repository has been archived by the owner on Jan 14, 2021. It is now read-only.

Commit

Permalink
Merge branch '1.5-development'
Browse files Browse the repository at this point in the history
* 1.5-development:
  Update to recommended settings
  Add badges
  Better markup in README.md
  added public statements
  Update README.md
  Update RootViewController.swift
  Update UIImage+Gif.swift
  Add build status badge
  Update .travis.yml
  Added swift2 update check message tracker
  • Loading branch information
bahlo committed Oct 13, 2015
2 parents fd935e6 + f5e936c commit ad6fdfc
Show file tree
Hide file tree
Showing 9 changed files with 86 additions and 61 deletions.
8 changes: 7 additions & 1 deletion .travis.yml
Original file line number Diff line number Diff line change
@@ -1,2 +1,8 @@
language: swift
language: objective-c
osx_image: xcode7

script:
- xctool
-project SwiftGif.xcodeproj -scheme SwiftGif
-sdk iphonesimulator build test
CODE_SIGNING_REQUIRED=NO CODE_SIGN_IDENTITY=""
11 changes: 5 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# SwiftGif
# SwiftGif [![Swift 2.0](https://img.shields.io/badge/Swift-2.0-orange.svg?style=flat)](https://developer.apple.com/swift/) [![Carthage compatible](https://img.shields.io/badge/Carthage-compatible-4BC51D.svg?style=flat)](https://github.com/Carthage/Carthage) [![CocoaPods](https://img.shields.io/cocoapods/v/SwiftGifOrigin.svg)](http://cocoadocs.org/docsets/SwiftGifOrigin) [![License MIT](https://img.shields.io/badge/License-MIT-blue.svg?style=flat)](https://github.com/Carthage/Carthage) [![Build Status](https://travis-ci.org/bahlo/SwiftGif.svg?branch=master)](https://travis-ci.org/bahlo/SwiftGif)

A small `UIImage` extension with gif support.

Expand All @@ -7,12 +7,11 @@ A small `UIImage` extension with gif support.
## Usage
Import the `Gif.swift` in your project and do the following:
```swift
// jeremy.gif
var url = NSBundle.mainBundle().URLForResource("jeremy", withExtension: "gif")
var imageData = NSData(contentsOfURL: url)

// Returns an animated UIImage
UIImage.animatedImageWithData(imageData)
let jeremyGif = UIImage.gifWithName("jeremy")

// Use the UIImage in your UIImageView
let imageView = UIImageView(image: jeremyGif)
```

## How does it work?
Expand Down
8 changes: 7 additions & 1 deletion SwiftGif.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -155,7 +155,8 @@
14A76430194EFBB800A74B1F /* Project object */ = {
isa = PBXProject;
attributes = {
LastUpgradeCheck = 0600;
LastSwiftUpdateCheck = 0700;
LastUpgradeCheck = 0700;
ORGANIZATIONNAME = "Arne Bahlo";
TargetAttributes = {
14A76437194EFBB800A74B1F = {
Expand Down Expand Up @@ -257,6 +258,7 @@
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
COPY_PHASE_STRIP = NO;
ENABLE_STRICT_OBJC_MSGSEND = YES;
ENABLE_TESTABILITY = YES;
GCC_C_LANGUAGE_STANDARD = gnu99;
GCC_DYNAMIC_NO_PIC = NO;
GCC_OPTIMIZATION_LEVEL = 0;
Expand Down Expand Up @@ -321,6 +323,7 @@
ASSETCATALOG_COMPILER_LAUNCHIMAGE_NAME = LaunchImage;
INFOPLIST_FILE = "$(SRCROOT)/SwiftGifDemo/Info.plist";
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
PRODUCT_BUNDLE_IDENTIFIER = "me.arne.${PRODUCT_NAME:rfc1034identifier}";
PRODUCT_NAME = "$(TARGET_NAME)";
};
name = Debug;
Expand All @@ -332,6 +335,7 @@
ASSETCATALOG_COMPILER_LAUNCHIMAGE_NAME = LaunchImage;
INFOPLIST_FILE = "$(SRCROOT)/SwiftGifDemo/Info.plist";
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
PRODUCT_BUNDLE_IDENTIFIER = "me.arne.${PRODUCT_NAME:rfc1034identifier}";
PRODUCT_NAME = "$(TARGET_NAME)";
};
name = Release;
Expand All @@ -351,6 +355,7 @@
INFOPLIST_FILE = SwiftGifTests/Info.plist;
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
METAL_ENABLE_DEBUG_INFO = YES;
PRODUCT_BUNDLE_IDENTIFIER = "me.arne.${PRODUCT_NAME:rfc1034identifier}";
PRODUCT_NAME = "$(TARGET_NAME)";
TEST_HOST = "$(BUNDLE_LOADER)";
};
Expand All @@ -367,6 +372,7 @@
INFOPLIST_FILE = SwiftGifTests/Info.plist;
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
METAL_ENABLE_DEBUG_INFO = NO;
PRODUCT_BUNDLE_IDENTIFIER = "me.arne.${PRODUCT_NAME:rfc1034identifier}";
PRODUCT_NAME = "$(TARGET_NAME)";
TEST_HOST = "$(BUNDLE_LOADER)";
};
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<Scheme
LastUpgradeVersion = "0600"
LastUpgradeVersion = "0700"
version = "1.3">
<BuildAction
parallelizeBuildables = "YES"
Expand All @@ -23,10 +23,10 @@
</BuildActionEntries>
</BuildAction>
<TestAction
buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
shouldUseLaunchSchemeArgsEnv = "YES"
buildConfiguration = "Debug">
shouldUseLaunchSchemeArgsEnv = "YES">
<Testables>
<TestableReference
skipped = "NO">
Expand All @@ -48,17 +48,21 @@
ReferencedContainer = "container:SwiftGif.xcodeproj">
</BuildableReference>
</MacroExpansion>
<AdditionalOptions>
</AdditionalOptions>
</TestAction>
<LaunchAction
buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
launchStyle = "0"
useCustomWorkingDirectory = "NO"
buildConfiguration = "Debug"
ignoresPersistentStateOnLaunch = "NO"
debugDocumentVersioning = "YES"
debugServiceExtension = "internal"
allowLocationSimulation = "YES">
<BuildableProductRunnable>
<BuildableProductRunnable
runnableDebuggingMode = "0">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "14A76437194EFBB800A74B1F"
Expand All @@ -71,12 +75,13 @@
</AdditionalOptions>
</LaunchAction>
<ProfileAction
buildConfiguration = "Release"
shouldUseLaunchSchemeArgsEnv = "YES"
savedToolIdentifier = ""
useCustomWorkingDirectory = "NO"
buildConfiguration = "Release"
debugDocumentVersioning = "YES">
<BuildableProductRunnable>
<BuildableProductRunnable
runnableDebuggingMode = "0">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "14A76437194EFBB800A74B1F"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
<dict>
<key>SchemeUserState</key>
<dict>
<key>SwiftGif.xcscheme</key>
<key>SwiftGif.xcscheme_^#shared#^_</key>
<dict>
<key>orderHint</key>
<integer>0</integer>
Expand Down
78 changes: 45 additions & 33 deletions SwiftGifCommon/UIImage+Gif.swift
Original file line number Diff line number Diff line change
Expand Up @@ -10,17 +10,30 @@ import UIKit
import ImageIO

extension UIImage {

public class func animatedImageWithData(data: NSData) -> UIImage? {
guard let source = CGImageSourceCreateWithData(data, nil) else { return nil }


public class func gifWithData(data: NSData) -> UIImage? {
guard let source = CGImageSourceCreateWithData(data, nil) else {
print("SwiftGif: Source for the image does not exist")
return nil
}
return UIImage.animatedImageWithSource(source)
}

class func delayForImageAtIndex(index: Int, source: CGImageSource!)
-> Double {

public class func gifWithName(name: String) -> UIImage? {
guard let bundleURL = NSBundle.mainBundle().URLForResource(name, withExtension: "gif") else {
print("SwiftGif: This image named \"\(name)\" does not exist")
return nil
}
guard let imageData = NSData(contentsOfURL: bundleURL) else {
print("SwiftGif: Cannot turn image named \"\(name)\" into NSData")
return nil
}
return gifWithData(imageData)
}

class func delayForImageAtIndex(index: Int, source: CGImageSource!) -> Double {
var delay = 0.1

// Get dictionaries
let cfProperties = CGImageSourceCopyPropertiesAtIndex(source, index, nil)
let gifProperties: CFDictionaryRef = unsafeBitCast(
Expand All @@ -37,17 +50,16 @@ extension UIImage {
delayObject = unsafeBitCast(CFDictionaryGetValue(gifProperties,
unsafeAddressOf(kCGImagePropertyGIFDelayTime)), AnyObject.self)
}

delay = delayObject as! Double

if delay < 0.1 {
delay = 0.1 // Make sure they're not too fast
}



return delay
}

class func gcdForPair(var a: Int?, var _ b: Int?) -> Int {
// Check if one of them is nil
if b == nil || a == nil {
Expand All @@ -59,19 +71,19 @@ extension UIImage {
return 0
}
}

// Swap for modulo
if a < b {
let c = a
a = b
b = c
}

// Get greatest common divisor
var rest: Int
while true {
rest = a! % b!

if rest == 0 {
return b! // Found it
} else {
Expand All @@ -80,70 +92,70 @@ extension UIImage {
}
}
}

class func gcdForArray(array: Array<Int>) -> Int {
if array.isEmpty {
return 1
}

var gcd = array[0]

for val in array {
gcd = UIImage.gcdForPair(val, gcd)
}

return gcd
}

public class func animatedImageWithSource(source: CGImageSource) -> UIImage? {
class func animatedImageWithSource(source: CGImageSource) -> UIImage? {
let count = CGImageSourceGetCount(source)
var images = [CGImageRef]()
var delays = [Int]()

// Fill arrays
for i in 0..<count {
// Add image
if let image = CGImageSourceCreateImageAtIndex(source, i, nil) {
images.append(image)
}

// At it's delay in cs
let delaySeconds = UIImage.delayForImageAtIndex(Int(i),
source: source)
delays.append(Int(delaySeconds * 1000.0)) // Seconds to ms
}

// Calculate full duration
let duration: Int = {
var sum = 0

for val: Int in delays {
sum += val
}

return sum
}()

// Get frames
let gcd = gcdForArray(delays)
var frames = [UIImage]()

var frame: UIImage
var frameCount: Int
for i in 0..<count {
frame = UIImage(CGImage: images[Int(i)])
frameCount = Int(delays[Int(i)] / gcd)

for _ in 0..<frameCount {
frames.append(frame)
}
}

// Heyhey
let animation = UIImage.animatedImageWithImages(frames,
duration: Double(duration) / 1000.0)

return animation
}

}
2 changes: 1 addition & 1 deletion SwiftGifDemo/Info.plist
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
<key>CFBundleExecutable</key>
<string>${EXECUTABLE_NAME}</string>
<key>CFBundleIdentifier</key>
<string>me.arne.${PRODUCT_NAME:rfc1034identifier}</string>
<string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
<key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string>
<key>CFBundleName</key>
Expand Down
17 changes: 7 additions & 10 deletions SwiftGifDemo/RootViewController.swift
Original file line number Diff line number Diff line change
Expand Up @@ -22,22 +22,19 @@ class RootViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()

var imageData = NSData(contentsOfURL: NSBundle.mainBundle()
.URLForResource("jeremy", withExtension: "gif")!)
let jeremy = UIImage.animatedImageWithData(imageData!)
var imageView = UIImageView(image: jeremy)
let jeremyGif = UIImage.gifWithName("jeremy")
let imageView = UIImageView(image: jeremyGif)
imageView.frame = CGRect(x: 0.0, y: 20.0, width: 350.0, height: 202.0)

view.addSubview(imageView)


imageData = NSData(contentsOfURL: NSBundle.mainBundle()
.URLForResource("adventure-time", withExtension: "gif")!)
let advTime = UIImage.animatedImageWithData(imageData!)
imageView = UIImageView(image: advTime)
imageView.frame = CGRect(x: 0.0, y: 222.0, width: 350.0, height: 202.0)
let imageData = NSData(contentsOfURL: NSBundle.mainBundle().URLForResource("adventure-time", withExtension: "gif")!)
let advTimeGif = UIImage.gifWithData(imageData!)
let imageView2 = UIImageView(image: advTimeGif)
imageView2.frame = CGRect(x: 0.0, y: 222.0, width: 350.0, height: 202.0)

view.addSubview(imageView)
view.addSubview(imageView2)
}

override func didReceiveMemoryWarning() {
Expand Down
2 changes: 1 addition & 1 deletion SwiftGifTests/Info.plist
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
<key>CFBundleExecutable</key>
<string>${EXECUTABLE_NAME}</string>
<key>CFBundleIdentifier</key>
<string>me.arne.${PRODUCT_NAME:rfc1034identifier}</string>
<string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
<key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string>
<key>CFBundleName</key>
Expand Down

0 comments on commit ad6fdfc

Please sign in to comment.