Добавить анимированное изображение Gif в Iphone UIImageView

80

Мне нужно загрузить анимированное изображение Gif с URL-адреса в UIImageview.

Когда я использовал обычный код, изображение не загружалось.

Есть ли другой способ загрузить анимированные изображения Gif?

Велмуруган
источник
мне нужно загрузить изображение со следующего URL-адреса в UIImageview .... feedads.g.doubleclick.net/~at/K_fHnmr7a7T0pru2TjQC29TsPYY/1/di
Велмуруган
Для быстрого
перехода

Ответы:

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];

Вы можете загрузить более одного изображения в формате GIF.

Вы можете разделить свой gif с помощью следующей команды ImageMagick :

convert +adjoin loading.gif out%d.gif
Ишу
источник
1
мне нужно загрузить изображение со следующего URL-адреса в UIImageview .... feedads.g.doubleclick.net/~at/K_fHnmr7a7T0pru2TjQC29TsPYY/1/di
Велмуруган
NSData * mydata = [[выделение NSData] initWithContentsOfURL: [NSURL URLWithString: myurl]]; UIImage * myimage = [[распределение UIImage] initWithData: imageData]; используйте это для чтения с URL-адреса, затем добавьте этот объект в массив
Ishu
8
IPhone OS не может и не будет правильно отображать анимированные изображения в формате GIF. Для этого нельзя использовать объект UIImage. Несмотря на то, что он поддерживает изображения в формате GIF, любая анимация будет отброшена, и будет показан только первый кадр. Так что, если вам нужно отобразить анимированный GIF в приложении для iPhone, вы облажались. Код должен быть написан ... Взгляните сюда: pliep.nl/blog/2009/04/…
fyasar
10
Вам просто нужно использовать веб-просмотр вместо просмотра изображений
Шрис Гарг
2
github.com/mayoff/uiimage-from-animated-gif просто используйте эту категорию, поскольку она автоматически делает все, что описано в ответе,
Майкл
53

Это нашло принятый ответ, но недавно я наткнулся на расширение UIImage + animatedGIF UIImage. Он предоставляет следующую категорию:

+[UIImage animatedImageWithAnimatedGIFURL:(NSURL *)url]

позволяя вам просто:

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

Работает как по волшебству.

Дом Виньярд
источник
1
Будет ли способ использовать файл непосредственно в проекте вместо загрузки gif с URL-адреса?
juliensaad
2
UIImage + animatedGIF ... одна из лучших категорий, которые я когда-либо видел ... спасибо @robmayoff
whyoz
22

Вот лучшее решение для использования Gif Image. Добавьте SDWebImage из Github в свой проект.

#import "UIImage+GIF.h"

_imageViewAnimatedGif.image= [UIImage sd_animatedGIFNamed:@"thumbnail"];
Арвинд Кумар
источник
ЭТО именно то, что я искал. Спасибо, мужик! Если я могу добавить кое-что: UIImageView не синхронизируется, но должен быть создан в раскадровке и связан с его IBOutlet :)
Люсия Белардинелли
12

Проверить эту ссылку

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

и импортируйте эти классы UIImage + animatedGIF.h, UIImage + animatedGIF.m

Используйте этот код

 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];

Надеюсь, это будет полезно

Mohit
источник
8

Если вы не хотите использовать стороннюю библиотеку,

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
    }
}

Использовать,

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

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

Убедитесь, что вы добавляете файл gif в проект, а не в папку .xcassets.

Суквон
источник
Ваш код вызывает: Поток 1: EXC_BAD_INSTRUCTION (code = EXC_I386_INVOP, subcode = 0x0) error!
Coder ACJHP
5

Это не соответствует требованию использования UIImageView, но, возможно, это упростит вам задачу. Вы рассматривали возможность использования UIWebView?

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

Если вы хотите, вместо ссылки на URL-адрес, для которого требуется Интернет, вы можете импортировать HTML-файл в свой проект Xcode и установить корень в строке.

Trevorgrayson
источник
3

Вот интересная библиотека: https://github.com/Flipboard/FLAnimatedImage

Я протестировал демонстрационный пример, и он отлично работает. Это дочерний элемент UIImageView. Так что я думаю, вы также можете использовать его непосредственно в своей раскадровке.

Ура

akdeveloper
источник
3

Я знаю, что ответ уже был одобрен, но трудно не попытаться поделиться тем, что я создал встроенную платформу, которая добавляет поддержку Gif в iOS, которая выглядит так же, как если бы вы использовали любой другой класс UIKit Framework.

Вот пример:

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

Загрузите последнюю версию с https://github.com/ObjSal/UIGifImage/releases

- Сал

ObjSal
источник
1

Если вам необходимо загрузить изображение в формате GIF из URL-адреса, вы всегда можете встроить GIF в тег изображения в файле UIWebView.

jd.
источник
1

SWIFT 3

Вот обновление для тех, кому нужна версия Swift !.

Несколько дней назад мне нужно было сделать что-то подобное. Я загружаю некоторые данные с сервера в соответствии с определенными параметрами, и тем временем я хотел показать другое изображение в формате gif «загрузка». Я искал вариант сделать это с помощью, UIImageViewно, к сожалению, я не нашел ничего, что можно было бы сделать без разделения изображений .gif. Поэтому я решил реализовать решение, используя a, UIWebViewи хочу им поделиться:

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)
    }
} 

Я сделал расширение, для UIViewкоторого добавляется UIWebViewподпредставление as и отображаются изображения .gif, просто передавая его имя.

Теперь у меня UIViewControllerесть UIViewименованный loadView, который является моим индикатором загрузки, и всякий раз, когда я хотел показать изображение .gif, я делал что-то вроде этого:

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
    }
}

когда я хотел изменить изображение в формате GIF, просто вызвал функцию configureLoadingView()с именем моего нового изображения в формате GIF и вызвал showLoadingView(),hideLoadingView() все работает нормально!

НО...

... если у вас есть разделенное изображение, вы можете анимировать его в одной строке с помощью UIImageстатического метода, который называется UIImage.animatedImageNamedследующим образом:

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

Из документов:

Этот метод загружает серию файлов, добавляя серию чисел к базовому имени файла, указанному в параметре name. Все изображения, включенные в анимированное изображение, должны иметь одинаковый размер и масштаб.

Или вы можете сделать это следующим UIImage.animatedImageWithImagesспособом:

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

Из документов:

Создает и возвращает анимированное изображение из существующего набора изображений. Все изображения, включенные в анимированное изображение, должны иметь одинаковый размер и масштаб.

маврикоконд
источник
0

Вы можете использовать https://github.com/Flipboard/FLAnimatedImage

#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:

Как было предложено выше, я использую FLAnimatedImage с FLAnimatedImageView. И я загружаю гифку как набор данных с xcassets. Это позволяет мне предоставлять разные гифки для iphone и ipad для внешнего вида и нарезки приложений. Это намного эффективнее, чем все, что я пробовал. Также легко приостановить, используя .stopAnimating ().

if let asset = NSDataAsset(name: "animation") {
    let gifData = asset.data
    let gif = FLAnimatedImage(animatedGIFData: gifData)
    imageView.animatedImage = gif
  }
Мэтт Беарсон
источник
0

С Swift и KingFisher

   lazy var animatedPart: AnimatedImageView = {
        let img = AnimatedImageView()
        if let src = Bundle.main.url(forResource: "xx", withExtension: "gif"){
            img.kf.setImage(with: src)
        }
        return img
   }()
черная жемчужина
источник