7 播放GIF动态图

严格来讲,播放GIF动态图不能算是iOS中的动画开发技术,由于许多应用在进行某些需求的动画处理时,会使用播放GIF动态图的方式,所以本节也将这一技术归纳进iOS动画开发技术中。

一般有两种方式进行GIF格式图片的播放,一种是将其渲染为UIWebView进行播放,一种是将GIF文件中储存的图片数据与图片时序信息获取出来,使用UIImageView帧动画方式进行GIF动态图片的播放。

7.1 使用UIWebView进行GIF动态图播放

将GIF文件渲染为UIWebView进行动态图播放具有使用简单,效能强的特点,但也有一个缺点,就是在通过UIWebView进行加载GIF文件时,往往会耗费一定的时间。

使用Xcode开发工具创建一个名为UIWebViewGIF的工程,把一个GIF动态图文件作为演示素材。在ViewController类的viewDidLoad方法中添加如下代码。

  override func viewDidLoad() {
        super.viewDidLoad()
        let web = UIWebView(frame: CGRect(x: 20, y: 100, width: 280, height: 200))
        //读取素材数据
        let gifData = try! Data(contentsOf: URL(fileURLWithPath: Bundle.main.path(forResource: "gifImage", ofType: "gif")!))
        web.load(gifData, mimeType: "image/gif", textEncodingName: "", baseURL: URL(fileURLWithPath: Bundle.main.path(forResource: "gifImage", ofType: "gif")!))
        self.view.addSubview(web)
    }

使用UIWebView加载GIF文件来播放GIF动态图这种方式播放的效果十分流畅,而且开发者不需要对播放过程做任何管理,全部由UIWebView来维护,若非有特殊需求,这种方式是开发中的首选。运行工程,效果如图6-21所示。

图6-21 使用UIWebView播放GIF动态图

7.2 使用UIImageView帧动画进行GIF动态图播放

实际上,GIF动态图文件中包含了一组图片及其信息数据,这些信息数据中记录着这一组图片中各张图片的播放时长等信息,开发者可以将图片和这些信息获取出来,使用UIImageView的帧动画技术进行动画播放。 使用Xcode开发工具创建一个名为UIImageViewGIF的工程,在ViewController类中引入如下框架用于处理GIF文件数据。

import ImageIO

在viewDidLoad方法中添加如下代码。

  override func viewDidLoad() {
        super.viewDidLoad()
        let imageView = UIImageView(frame: CGRect(x: 20, y: 100, width: 280, height: 200))
        self.view.addSubview(imageView)
        let dataPath = Bundle.main.path(forResource: "gifImage", ofType: "gif")
        //获取GIF文件数据
        let source = CGImageSourceCreateWithURL(URL(fileURLWithPath: dataPath!) as CFURL, nil)
        //获取GIF文件中图片的个数
        let count = CGImageSourceGetCount(source!)
        //定义一个变量记录gif播放一轮的时间
        var allTime:Float = 0.0
        //存放图片
        var imageArray = Array<UIImage>()
        for i in 0..<count{
            let image = CGImageSourceCreateImageAtIndex(source!, i, nil)
            imageArray.append(UIImage(cgImage: image!))
            //获取图片信息
            let info = CGImageSourceCopyPropertiesAtIndex(source!, i, nil) as! Dictionary<String,Any>
            let timeDic = info[kCGImagePropertyGIFDictionary as String] as! Dictionary<String,Any>
            let time = timeDic[kCGImagePropertyGIFDelayTime as String]
            allTime += time as! Float
        }
        imageView.animationImages = imageArray
        imageView.animationDuration = TimeInterval(allTime)
        imageView.animationRepeatCount = -1
        imageView.startAnimating()
    }

可以发现,上面的方法十分繁琐,如果运行工程,可以看到这种方式播放的GIF动态图流畅性和性能也不如使用UIWebView的效果好,然而这种方式毕竟是使用UIImageView原生的方法来进行GIF动态播放的展示,在某些情况下十分易于扩展,读者可根据需求进行自由选择。