Fügen Sie ein animiertes Gif-Bild in Iphone UIImageView hinzu


80

Ich muss ein animiertes Gif-Bild von einer URL in UIImageview laden.

Wenn ich den normalen Code verwendet habe, wurde das Bild nicht geladen.

Gibt es eine andere Möglichkeit, animierte Gif-Bilder zu laden?


Ich muss das Bild von der folgenden URL in UIImageview laden .... feedads.g.doubleclick.net/~at/K_fHnmr7a7T0pru2TjQC29TsPYY/1/di
Velmurugan

Gehen Sie über diesen Link für schnell: stackoverflow.com/questions/27919620/…
Mr.Javed Multani

Antworten:


138
UIImageView* animatedImageView = [[UIImageView alloc] initWithFrame:self.view.bounds];
animatedImageView.animationImages = [NSArray arrayWithObjects:    
                               [UIImage imageNamed:@"image1.gif"],
                               [UIImage imageNamed:@"image2.gif"],
                               [UIImage imageNamed:@"image3.gif"],
                               [UIImage imageNamed:@"image4.gif"], nil];
animatedImageView.animationDuration = 1.0f;
animatedImageView.animationRepeatCount = 0;
[animatedImageView startAnimating];
[self.view addSubview: animatedImageView];

Sie können mehr als ein GIF-Bild laden.

Sie können Ihr GIF mit dem folgenden ImageMagick- Befehl teilen :

convert +adjoin loading.gif out%d.gif

1
Ich muss das Bild von der folgenden URL in UIImageview laden .... feedads.g.doubleclick.net/~at/K_fHnmr7a7T0pru2TjQC29TsPYY/1/di
Velmurugan

NSData * mydata = [[NSData alloc] initWithContentsOfURL: [NSURL URLWithString: myurl]]; UIImage * myimage = [[UIImage alloc] initWithData: imageData]; Verwenden Sie dies zum Lesen von der URL und fügen Sie dieses Objekt dem Array hinzu
Ishu

8
Das iPhone OS kann und wird animierte GIF-Bilder nicht richtig anzeigen. Das UIImage-Objekt kann hierfür nicht verwendet werden. Obwohl GIF-Bilder unterstützt werden, werden alle Animationen verworfen und nur das erste Bild angezeigt. Wenn Sie also ein animiertes GIF in einer iPhone-App anzeigen müssen, sind Sie fertig. Code muss geschrieben werden ... Schauen Sie hier: pliep.nl/blog/2009/04/…
fyasar

10
Sie müssen nur die
Webansicht

2
github.com/mayoff/uiimage-from-animated-gif Verwenden Sie einfach diese Kategorie, da dadurch alles, was in der Antwort beschrieben wird, automatisch ausgeführt wird
Michael

53

Dies hat eine akzeptierte Antwort gefunden, aber ich bin kürzlich auf die UIImage + animierte GIF UIImage-Erweiterung gestoßen. Es bietet die folgende Kategorie:

+[UIImage animatedImageWithAnimatedGIFURL:(NSURL *)url]

So können Sie einfach:

#import "UIImage+animatedGIF.h"
UIImage* mygif = [UIImage animatedImageWithAnimatedGIFURL:[NSURL URLWithString:@"http://en.wikipedia.org/wiki/File:Rotating_earth_(large).gif"]];

Funktioniert wie Magie.


1
Gibt es eine Möglichkeit, eine Datei direkt im Projekt zu verwenden, anstatt das GIF von einer URL zu laden?
Juliensaad

2
UIImage + animiertes GIF ... eine der besten Kategorien, die ich je gesehen habe ... danke @robmayoff
whyoz

22

Hier ist die beste Lösung für die Verwendung von Gif Image. Fügen Sie SDWebImage von Github in Ihr Projekt ein.

#import "UIImage+GIF.h"

_imageViewAnimatedGif.image= [UIImage sd_animatedGIFNamed:@"thumbnail"];

DAS ist genau das, wonach ich gesucht habe. Danke mann! Wenn ich etwas hinzufügen kann: Die UIImageView ist nicht synthetisiert, sondern sollte im Storyboard erstellt und mit ihrem IBOutlet verknüpft werden :)
Lucia Belardinelli

12

Überprüfen Sie diesen Link

https://github.com/mayoff/uiimage-from-animated-gif/blob/master/uiimage-from-animated-gif/UIImage%2BanimatedGIF.h

und importieren Sie diese Klassen UIImage + animiertes GIF.h, UIImage + animiertes GIF.m

Verwenden Sie diesen Code

 NSURL *urlZif = [[NSBundle mainBundle] URLForResource:@"dots64" withExtension:@"gif"];
 NSString *path=[[NSBundle mainBundle]pathForResource:@"bar180" ofType:@"gif"];
 NSURL *url=[[NSURL alloc] initFileURLWithPath:path];
 imageVw.image= [UIImage animatedImageWithAnimatedGIFURL:url];

Hoffe das ist hilfreich


8

Wenn Sie keine Bibliothek von Drittanbietern verwenden möchten,

extension UIImageView {
    func setGIFImage(name: String, repeatCount: Int = 0 ) {
        DispatchQueue.global().async {
            if let gif = UIImage.makeGIFFromCollection(name: name, repeatCount: repeatCount) {
                DispatchQueue.main.async {
                    self.setImage(withGIF: gif)
                    self.startAnimating()
                }
            }
        }
    }

    private func setImage(withGIF gif: GIF) {
        animationImages = gif.images
        animationDuration = gif.durationInSec
        animationRepeatCount = gif.repeatCount
    }
}

extension UIImage {
    class func makeGIFFromCollection(name: String, repeatCount: Int = 0) -> GIF? {
        guard let path = Bundle.main.path(forResource: name, ofType: "gif") else {
            print("Cannot find a path from the file \"\(name)\"")
            return nil
        }

        let url = URL(fileURLWithPath: path)
        let data = try? Data(contentsOf: url)
        guard let d = data else {
            print("Cannot turn image named \"\(name)\" into data")
            return nil
        }

        return makeGIFFromData(data: d, repeatCount: repeatCount)
    }

    class func makeGIFFromData(data: Data, repeatCount: Int = 0) -> GIF? {
        guard let source = CGImageSourceCreateWithData(data as CFData, nil) else {
            print("Source for the image does not exist")
            return nil
        }

        let count = CGImageSourceGetCount(source)
        var images = [UIImage]()
        var duration = 0.0

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

                let delaySeconds = UIImage.delayForImageAtIndex(Int(i),
                                                                source: source)
                duration += delaySeconds
            }
        }

        return GIF(images: images, durationInSec: duration, repeatCount: repeatCount)
    }

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

        // Get dictionaries
        let cfProperties = CGImageSourceCopyPropertiesAtIndex(source, index, nil)
        let gifPropertiesPointer = UnsafeMutablePointer<UnsafeRawPointer?>.allocate(capacity: 0)
        if CFDictionaryGetValueIfPresent(cfProperties, Unmanaged.passUnretained(kCGImagePropertyGIFDictionary).toOpaque(), gifPropertiesPointer) == false {
            return delay
        }

        let gifProperties:CFDictionary = unsafeBitCast(gifPropertiesPointer.pointee, to: CFDictionary.self)

        // Get delay time
        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 ?? 0

        return delay
    }
}

class GIF: NSObject {
    let images: [UIImage]
    let durationInSec: TimeInterval
    let repeatCount: Int

    init(images: [UIImage], durationInSec: TimeInterval, repeatCount: Int = 0) {
        self.images = images
        self.durationInSec = durationInSec
        self.repeatCount = repeatCount
    }
}

Benutzen,

override func viewDidLoad() {
    super.viewDidLoad()
    imageView.setGIFImage(name: "gif_file_name")
}

override func viewDidDisappear(_ animated: Bool) {
    super.viewDidDisappear(animated)
    imageView.stopAnimating()
}

Stellen Sie sicher, dass Sie die GIF-Datei im Projekt und nicht im Ordner .xcassets hinzufügen.


Ihre Code-Couses: Thread 1: EXC_BAD_INSTRUCTION (Code = EXC_I386_INVOP, Subcode = 0x0) Fehler!
Coder ACJHP

5

Dies entspricht nicht der Anforderung, ein UIImageView zu verwenden, aber möglicherweise würde dies die Dinge für Sie vereinfachen. Haben Sie überlegt, ein UIWebView zu verwenden?

NSString *gifUrl = @"http://gifs.com";
NSURL *url = [NSURL URLWithString: gifUrl];
[webView loadRequest: [NSURLRequest requestWithURL:url]

Wenn Sie möchten, können Sie anstelle einer Verknüpfung mit einer URL, für die Internet erforderlich ist, eine HTML-Datei in Ihr Xcode-Projekt importieren und den Stamm in der Zeichenfolge festlegen.



3

Ich weiß, dass eine Antwort bereits genehmigt wurde, aber es ist schwierig, nicht zu teilen, dass ich ein eingebettetes Framework erstellt habe, das iOS Gif-Unterstützung hinzufügt und sich so anfühlt, als ob Sie eine andere UIKit Framework-Klasse verwenden würden.

Hier ist ein Beispiel:

UIGifImage *gif = [[UIGifImage alloc] initWithData:imageData];
anUiImageView.image = gif;

Laden Sie die neueste Version von https://github.com/ObjSal/UIGifImage/releases herunter

- Sal


1

Wenn Sie das GIF-Bild von der URL laden müssen, können Sie das GIF jederzeit in ein Bild-Tag in a einbetten UIWebView.


1

SWIFT 3

Hier ist das Update für diejenigen, die die Swift-Version benötigen!.

Vor ein paar Tagen musste ich so etwas machen. Ich lade einige Daten von einem Server nach bestimmten Parametern und wollte in der Zwischenzeit ein anderes GIF-Bild von "Laden" zeigen. Ich suchte nach einer Option, um es mit einem zu tun, UIImageViewaber leider habe ich nichts gefunden, um es zu tun, ohne die .gif-Bilder zu teilen. Also habe ich beschlossen, eine Lösung mit a zu implementieren UIWebViewund möchte sie teilen:

extension UIView{
    func animateWithGIF(name: String){
        let htmlString: String =    "<!DOCTYPE html><html><head><title></title></head>" +
                                        "<body style=\"background-color: transparent;\">" +
                                            "<img src=\""+name+"\" align=\"middle\" style=\"width:100%;height:100%;\">" +
                                        "</body>" +
                                    "</html>"

        let path: NSString = Bundle.main.bundlePath as NSString
        let baseURL: URL = URL(fileURLWithPath: path as String) // to load images just specifying its name without full path

        let frame = CGRect(x: 0, y: 0, width: self.frame.width, height: self.frame.height)
        let gifView = UIWebView(frame: frame)

        gifView.isOpaque = false // The drawing system composites the view normally with other content.
        gifView.backgroundColor = UIColor.clear
        gifView.loadHTMLString(htmlString, baseURL: baseURL)

        var s: [UIView] = self.subviews 
        for i in 0 ..< s.count {
            if s[i].isKind(of: UIWebView.self) { s[i].removeFromSuperview() }
        }

        self.addSubview(gifView)
    }

    func animateWithGIF(url: String){
        self.animateWithGIF(name: url)
    }
} 

Ich habe eine Erweiterung erstellt, für UIViewdie eine UIWebViewUnteransicht als hinzugefügt wird und die GIF-Bilder angezeigt werden, die gerade ihren Namen übergeben.

Jetzt habe UIViewControllerich in meinem eine UIView"ladende Ansicht", die meine "Laden" -Anzeige ist, und wann immer ich das .gif-Bild zeigen wollte, habe ich so etwas gemacht:

class ViewController: UIViewController {
    @IBOutlet var loadingView: UIView!

    override func viewWillAppear(_ animated: Bool) {
        super.viewWillAppear(animated)
        configureLoadingView(name: "loading.gif")
    }

    override func viewDidLoad() {
        super.viewDidLoad()
        // .... some code
        // show "loading" image
        showLoadingView()
    }

    func showLoadingView(){
        loadingView.isHidden = false
    }
    func hideLoadingView(){
        loadingView.isHidden = true
    }
    func configureLoadingView(name: String){
        loadingView.animateWithGIF(name: "name")// change the image
    }
}

Wenn ich das GIF-Bild ändern wollte, rief ich einfach die Funktion configureLoadingView()mit dem Namen meines neuen GIF-Bildes auf und rief auf showLoadingView():hideLoadingView() funktioniert alles einwandfrei!.

ABER...

... wenn Sie das Bild geteilt haben, können Sie es mit einer UIImagestatischen Methode UIImage.animatedImageNamedwie folgt in einer einzelnen Zeile animieren :

imageView.image = UIImage.animatedImageNamed("imageName", duration: 1.0)

Aus den Dokumenten:

Diese Methode lädt eine Reihe von Dateien, indem eine Reihe von Zahlen an den im Parameter name angegebenen Basisdateinamen angehängt wird. Alle im animierten Bild enthaltenen Bilder sollten dieselbe Größe und denselben Maßstab haben.

Oder Sie können es mit der UIImage.animatedImageWithImagesMethode wie folgt machen:

let images: [UIImage] = [UIImage(named: "imageName1")!,
                                            UIImage(named: "imageName2")!,
                                            ...,
                                            UIImage(named: "imageNameN")!]
imageView.image = UIImage.animatedImage(with: images, duration: 1.0)

Aus den Dokumenten:

Erstellt ein animiertes Bild aus einem vorhandenen Satz von Bildern und gibt es zurück. Alle im animierten Bild enthaltenen Bilder sollten dieselbe Größe und denselben Maßstab haben.


0

Sie können https://github.com/Flipboard/FLAnimatedImage verwenden

#import "FLAnimatedImage.h"
NSData *dt=[NSData dataWithContentsOfFile:path];
imageView1 = [[FLAnimatedImageView alloc] init];
FLAnimatedImage *image1 = [FLAnimatedImage animatedImageWithGIFData:dt];
imageView1.animatedImage = image1;
imageView1.frame = CGRectMake(0, 5, 168, 80);
[self.view addSubview:imageView1];

0

Swift 3:

Wie oben vorgeschlagen, verwende ich FLAnimatedImage mit einer FLAnimatedImageView. Und ich lade das GIF als Datensatz von xcassets. Auf diese Weise kann ich verschiedene Gifs für iPhone und iPad für das Erscheinungsbild und das Schneiden von Apps bereitstellen. Dies ist weitaus performanter als alles andere, was ich versucht habe. Es ist auch einfach, mit .stopAnimating () anzuhalten.

if let asset = NSDataAsset(name: "animation") {
    let gifData = asset.data
    let gif = FLAnimatedImage(animatedGIFData: gifData)
    imageView.animatedImage = gif
  }
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.