如何在 Swift 中加载 GIF 图像?

我有一个字符串与一个网址的 GIF 旗帜,我需要放入应用程序。

我的代码:

func showAdd(){
Request.get("http://www.kyst.no/api/?apiMode=advertisement&lang=no", { (error: NSError?, data: NSData, text: NSString?) -> () in
let jsonResult: Dictionary = NSJSONSerialization.JSONObjectWithData(data, options: NSJSONReadingOptions.MutableContainers, error: nil) as Dictionary<String, AnyObject>
var banner : NSString = jsonResult["advertisement"]!["banner"] as NSString
self.addViewImage.image = UIImage.animatedImageNamed(banner, duration: 1)
})
}

但什么都没发生,请帮帮我。

178197 次浏览

Load GIF image Swift :

## Reference.

#1 : Copy the swift file from This Link :

#2 : Load GIF image Using Name

    let jeremyGif = UIImage.gifImageWithName("funny")
let imageView = UIImageView(image: jeremyGif)
imageView.frame = CGRect(x: 20.0, y: 50.0, width: self.view.frame.size.width - 40, height: 150.0)
view.addSubview(imageView)

#3 : Load GIF image Using Data

    let imageData = try? Data(contentsOf: Bundle.main.url(forResource: "play", withExtension: "gif")!)
let advTimeGif = UIImage.gifImageWithData(imageData!)
let imageView2 = UIImageView(image: advTimeGif)
imageView2.frame = CGRect(x: 20.0, y: 220.0, width:
self.view.frame.size.width - 40, height: 150.0)
view.addSubview(imageView2)

#4 : Load GIF image Using URL

    let gifURL : String = "http://www.gifbin.com/bin/4802swswsw04.gif"
let imageURL = UIImage.gifImageWithURL(gifURL)
let imageView3 = UIImageView(image: imageURL)
imageView3.frame = CGRect(x: 20.0, y: 390.0, width: self.view.frame.size.width - 40, height: 150.0)
view.addSubview(imageView3)

Download Demo Code

OUTPUT :

iPhone 8 / iOS 11 / xCode 9

enter image description here

//
//  iOSDevCenters+GIF.swift
//  GIF-Swift
//
//  Created by iOSDevCenters on 11/12/15.
//  Copyright © 2016 iOSDevCenters. All rights reserved.
//
import UIKit
import ImageIO




extension UIImage {


public class func gifImageWithData(data: NSData) -> UIImage? {
guard let source = CGImageSourceCreateWithData(data, nil) else {
print("image doesn't exist")
return nil
}


return UIImage.animatedImageWithSource(source: source)
}


public class func gifImageWithURL(gifUrl:String) -> UIImage? {
guard let bundleURL = NSURL(string: gifUrl)
else {
print("image named \"\(gifUrl)\" doesn't exist")
return nil
}
guard let imageData = NSData(contentsOf: bundleURL as URL) else {
print("image named \"\(gifUrl)\" into NSData")
return nil
}


return gifImageWithData(data: imageData)
}


public class func gifImageWithName(name: String) -> UIImage? {
guard let bundleURL = Bundle.main
.url(forResource: name, withExtension: "gif") else {
print("SwiftGif: This image named \"\(name)\" does not exist")
return nil
}


guard let imageData = NSData(contentsOf: bundleURL) else {
print("SwiftGif: Cannot turn image named \"\(name)\" into NSData")
return nil
}


return gifImageWithData(data: imageData)
}


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


let cfProperties = CGImageSourceCopyPropertiesAtIndex(source, index, nil)
let gifProperties: CFDictionary = unsafeBitCast(CFDictionaryGetValue(cfProperties, Unmanaged.passUnretained(kCGImagePropertyGIFDictionary).toOpaque()), to: CFDictionary.self)


var delayObject: AnyObject = unsafeBitCast(CFDictionaryGetValue(gifProperties, Unmanaged.passUnretained(kCGImagePropertyGIFUnclampedDelayTime).toOpaque()), to: AnyObject.self)


if delayObject.doubleValue == 0 {
delayObject = unsafeBitCast(CFDictionaryGetValue(gifProperties, Unmanaged.passUnretained(kCGImagePropertyGIFDelayTime).toOpaque()), to: AnyObject.self)
}


delay = delayObject as! Double


if delay < 0.1 {
delay = 0.1
}


return delay
}


class func gcdForPair(a: Int?, _ b: Int?) -> Int {
var a = a
var b = b
if b == nil || a == nil {
if b != nil {
return b!
} else if a != nil {
return a!
} else {
return 0
}
}


if a! < b! {
let c = a!
a = b!
b = c
}


var rest: Int
while true {
rest = a! % b!


if rest == 0 {
return b!
} else {
a = b!
b = rest
}
}
}


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


var gcd = array[0]


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


return gcd
}


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


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


let delaySeconds = UIImage.delayForImageAtIndex(index: Int(i), source: source)
delays.append(Int(delaySeconds * 1000.0)) // Seconds to ms
}


let duration: Int = {
var sum = 0


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


return sum
}()


let gcd = gcdForArray(array: 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)
}
}


let animation = UIImage.animatedImage(with: frames, duration: Double(duration) / 1000.0)


return animation
}
}

Here is the file updated for Swift 3

First install a pod :-

pod 'SwiftGifOrigin'

and import in your class

import SwiftGifOrigin

then write this code in viewDidiload method

yourImageView.image = UIImage.gif(name: "imageName")

Note:- plz do not include the file extension in the gif file name. Ex:-

//Don't Do this
yourImageView.image = UIImage.gif(name: "imageName.gif")

See source: https://github.com/swiftgif/SwiftGif

Simple extension for local gifs. Gets all the images from the gif and adds it to the imageView animationImages.

extension UIImageView {
static func fromGif(frame: CGRect, resourceName: String) -> UIImageView? {
guard let path = Bundle.main.path(forResource: resourceName, ofType: "gif") else {
print("Gif does not exist at that path")
return nil
}
let url = URL(fileURLWithPath: path)
guard let gifData = try? Data(contentsOf: url),
let source =  CGImageSourceCreateWithData(gifData as CFData, nil) else { return nil }
var images = [UIImage]()
let imageCount = CGImageSourceGetCount(source)
for i in 0 ..< imageCount {
if let image = CGImageSourceCreateImageAtIndex(source, i, nil) {
images.append(UIImage(cgImage: image))
}
}
let gifImageView = UIImageView(frame: frame)
gifImageView.animationImages = images
return gifImageView
}
}

To Use:

 guard let confettiImageView = UIImageView.fromGif(frame: view.frame, resourceName: "confetti") else { return }
view.addSubview(confettiImageView)
confettiImageView.startAnimating()

Repeat and duration customizations using UIImageView APIs.

confettiImageView.animationDuration = 3
confettiImageView.animationRepeatCount = 1

When you are done animating the gif and want to release the memory.

confettiImageView.animationImages = nil

This is working for me

Podfile:

platform :ios, '9.0'
use_frameworks!


target '<Your Target Name>' do
pod 'SwiftGifOrigin', '~> 1.7.0'
end

Usage:

// An animated UIImage
let jeremyGif = UIImage.gif(name: "jeremy")


// A UIImageView with async loading
let imageView = UIImageView()
imageView.loadGif(name: "jeremy")


// A UIImageView with async loading from asset catalog(from iOS9)
let imageView = UIImageView()
imageView.loadGif(asset: "jeremy")

For more information follow this link: https://github.com/swiftgif/SwiftGif

You can try this new library. JellyGif respects Gif frame duration while being highly CPU & Memory performant. It works great with UITableViewCell & UICollectionViewCell too. To get started you just need to

import JellyGif


let imageView = JellyGifImageView(frame: CGRect(x: 0, y: 0, width: 100, height: 100))


//Animates Gif from the main bundle
imageView.startGif(with: .name("Gif name"))


//Animates Gif with a local path
let url = URL(string: "Gif path")!
imageView.startGif(with: .localPath(url))


//Animates Gif with data
imageView.startGif(with: .data(Data))

For more information you can look at its README

it would be great if somebody told to put gif into any folder instead of assets folder