Muszę załadować animowany obraz Gif z adresu URL w UIImageview.
Kiedy użyłem normalnego kodu, obraz się nie załadował.
Czy jest jakiś inny sposób ładowania animowanych obrazów Gif?
Muszę załadować animowany obraz Gif z adresu URL w UIImageview.
Kiedy użyłem normalnego kodu, obraz się nie załadował.
Czy jest jakiś inny sposób ładowania animowanych obrazów Gif?
Odpowiedzi:
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];
Możesz załadować więcej niż jeden obraz GIF.
Możesz podzielić swój gif za pomocą następującego polecenia ImageMagick :
convert +adjoin loading.gif out%d.gif
To znalazło akceptowaną odpowiedź, ale ostatnio natknąłem się na rozszerzenie UIImage + animatedGIF UIImage. Zapewnia następującą kategorię:
+[UIImage animatedImageWithAnimatedGIFURL:(NSURL *)url]
co pozwala po prostu:
#import "UIImage+animatedGIF.h"
UIImage* mygif = [UIImage animatedImageWithAnimatedGIFURL:[NSURL URLWithString:@"http://en.wikipedia.org/wiki/File:Rotating_earth_(large).gif"]];
Działa jak magia.
Oto najlepsze rozwiązanie do korzystania z obrazu Gif. Dodaj SDWebImage z Github do swojego projektu.
#import "UIImage+GIF.h"
_imageViewAnimatedGif.image= [UIImage sd_animatedGIFNamed:@"thumbnail"];
Sprawdź ten link
i zaimportuj te klasy UIImage + animatedGIF.h, UIImage + animatedGIF.m
Użyj tego kodu
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];
Mam nadzieję, że to jest pomocne
Jeśli nie chcesz korzystać z biblioteki innej firmy,
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
}
}
Używać,
override func viewDidLoad() {
super.viewDidLoad()
imageView.setGIFImage(name: "gif_file_name")
}
override func viewDidDisappear(_ animated: Bool) {
super.viewDidDisappear(animated)
imageView.stopAnimating()
}
Upewnij się, że dodajesz plik gif do projektu, a nie do folderu .xcassets.
Nie spełnia to wymagań korzystania z UIImageView, ale może to uprościłoby sprawę. Czy rozważałeś użycie UIWebView?
NSString *gifUrl = @"http://gifs.com";
NSURL *url = [NSURL URLWithString: gifUrl];
[webView loadRequest: [NSURLRequest requestWithURL:url]
Jeśli chcesz, zamiast łączyć się z adresem URL, który wymaga Internetu, możesz zaimportować plik HTML do projektu Xcode i ustawić katalog główny w ciągu.
Oto interesująca biblioteka: https://github.com/Flipboard/FLAnimatedImage
Przetestowałem przykład demo i działa świetnie. Jest to element potomny UIImageView. Myślę więc, że możesz go również użyć bezpośrednio w swoim Storyboard.
Twoje zdrowie
Wiem, że odpowiedź została już zatwierdzona, ale trudno nie spróbować podzielić się tym, że stworzyłem wbudowany framework, który dodaje obsługę Gif do iOS, który wygląda tak, jakbyś używał innej klasy UIKit Framework.
Oto przykład:
UIGifImage *gif = [[UIGifImage alloc] initWithData:imageData];
anUiImageView.image = gif;
Pobierz najnowszą wersję z https://github.com/ObjSal/UIGifImage/releases
- Sal
SWIFT 3
Oto aktualizacja dla tych, którzy potrzebują wersji Swift !.
Kilka dni temu musiałem zrobić coś takiego. Ładuję dane z serwera według określonych parametrów, aw międzyczasie chciałem pokazać inny obraz gif „wczytywania”. Szukałem opcji zrobienia tego za pomocą pliku, UIImageView
ale niestety nie znalazłem czegoś, co mogłoby to zrobić bez podzielenia obrazów .gif. Postanowiłem więc wdrożyć rozwiązanie za pomocą UIWebView
a i chcę się nim podzielić:
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)
}
}
Zrobiłem rozszerzenie, UIView
które dodaje UIWebView
widok podrzędny as i wyświetla obrazy .gif, przekazując tylko jego nazwę.
Teraz w moim UIViewController
mam UIView
nazwany `` loadingView '', który jest moim wskaźnikiem `` ładowania '' i kiedykolwiek chciałem wyświetlić obraz .gif, zrobiłem coś takiego:
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
}
}
kiedy chciałem zmienić obraz gif, po prostu wywołałem funkcję configureLoadingView()
z nazwą mojego nowego obrazu .gif i wywołałem showLoadingView()
, hideLoadingView()
wszystko działa dobrze !.
ALE...
... jeśli masz podzielony obraz, możesz go animować w pojedynczej linii za pomocą UIImage
statycznej metody o nazwie UIImage.animatedImageNamed
:
imageView.image = UIImage.animatedImageNamed("imageName", duration: 1.0)
Z dokumentów:
Ta metoda ładuje serię plików, dołączając serię liczb do podstawowej nazwy pliku podanej w parametrze name. Wszystkie obrazy zawarte w animowanym obrazie powinny mieć ten sam rozmiar i skalę.
Lub możesz to zrobić za pomocą takiej UIImage.animatedImageWithImages
metody:
let images: [UIImage] = [UIImage(named: "imageName1")!,
UIImage(named: "imageName2")!,
...,
UIImage(named: "imageNameN")!]
imageView.image = UIImage.animatedImage(with: images, duration: 1.0)
Z dokumentów:
Tworzy i zwraca animowany obraz z istniejącego zestawu obrazów. Wszystkie obrazy zawarte w animowanym obrazie powinny mieć ten sam rozmiar i skalę.
Możesz użyć 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];
Swift 3:
Jak zasugerowano powyżej, używam FLAnimatedImage z FLAnimatedImageView. Ładuję gif jako zestaw danych z xcassets. Dzięki temu mogę udostępniać różne gify na iPhone'a i iPada do celów związanych z wyglądem i fragmentowaniem aplikacji. To jest o wiele bardziej wydajne niż cokolwiek innego, czego próbowałem. Można też łatwo wstrzymać pracę za pomocą .stopAnimating ().
if let asset = NSDataAsset(name: "animation") {
let gifData = asset.data
let gif = FLAnimatedImage(animatedGIFData: gifData)
imageView.animatedImage = gif
}
Z Swift i 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
}()