JellyGif 版本 1.0.2

JellyGif 版本 1.0.2

Linh Ta 维护。



JellyGif 版本 1.0.2

Language Platform Pod License Cover Image

轻量级、高性能、内存高效的 Gif 框架

功能

  • 尊重 Gif 帧间隔
  • 优化 CPU 和内存性能
  • 考虑到 UITableViewCell 和 UICollectionViewCell 设计
  • 完全控制所有细节,例如准备过程、动画质量、输出图像质量等...
  • 可扩展且易于使用

安装

使用 CocoaPods

source 'https://cocoapods.org.cn/pods/JellyGif'
use_frameworks!
pod 'JellyGif'

用法

开始使用最简单的方法是使用 JellyGifImageView 并调用 startGif(with:)

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

为了充分利用 JellyGif 的全部功能,请使用 JellyGifAnimator 并遵守它的 JellyGifAnimatorDelegate

import JellyGif

let imageView = UIImageView(CGRect(x: 0, y: 0, width: 100, height: 100))
let animator = JellyGifAnimator(imageInfo: .name("Gif name"), pixelSize: .custom(350), animationQuality: .best)
animator.delegate = self

//JellyGifAnimatorDelegate
func gifAnimatorIsReady(_ sender: JellyGifAnimator) {
  sender.startAnimation()
}

func imageViewForAnimator(_ sender: JellyGifAnimator) -> UIImageView? { 
  return imageView
}

func gifAnimatorDidChangeImage(_ image: UIImage, sender: JellyGifAnimator) {
  //Use this method if you want to manually update Gif frame instead of using an UIImageView
}

JellyGifAnimator 允您控制每个方面的 Gif,包括最大输出大小 - pixelSize 和每秒帧数 - animationQuality。当 pixelSize 属性接近图像持有器的实际大小时,内存占用将更小,CPU 性能将更好。

UICollectionView & UITableView

要使用 JellyGifAnimatorUICollectionViewUITableView,请在 UICollectionViewUITableView 的拥有者内部创建一个 JellyGifAnimator 字典,并符合 JellyGifAnimatorDelegate

import JellyGif

class ViewController: UIViewController {
  var gifNames: [String] = []
  var animators: [IndexPath: JellyGifAnimator] = [:]
    
  //Your code
  //...
}

extension ViewController: UICollectionViewDelegate, UICollectionViewDataSource, UICollectionViewDelegateFlowLayout {
  //Your Code
  //...
  
  func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
    //dequeue cell
    //...
    
    let gifName = gifNames[indexPath.item]
    
    if animators[indexPath] == nil {
        let animator = JellyGifAnimator(imageInfo: .name(gifName), pixelSize: .custom(350), animationQuality: .best)
        animators[indexPath] = animator
    }

    //If the Gif is not ready, show a placeholder image - which is the first frame of the Gif instead
    if animators[indexPath]?.isReady != true {
        cell.imageView.image = animators[indexPath]?.placeholder
    }

    animators[indexPath]?.delegate = self

    return cell
  }
  
  func collectionView(_ collectionView: UICollectionView, willDisplay cell: UICollectionViewCell, forItemAt indexPath: IndexPath) {
    if animators[indexPath]?.isReady == true {
      animators[indexPath]?.startAnimation()
    } else {
      animators[indexPath]?.prepareAnimation()
    }
  }

  func collectionView(_ collectionView: UICollectionView, didEndDisplaying cell: UICollectionViewCell, forItemAt indexPath: IndexPath) {
    //Pause animation and the preparation process if the cell is not visible
    animators[indexPath]?.pauseAnimation()
    animators[indexPath]?.stopPreparingAnimation()
  }
}

extension ViewController: JellyGifAnimatorDelegate {
  func gifAnimatorIsReady(_ sender: JellyGifAnimator) {
    sender.startAnimation()
  }

  func imageViewForAnimator(_ sender: JellyGifAnimator) -> UIImageView? { 
    for indexPath in collectionView.indexPathsForVisibleItems {
      if animators[indexPath] === sender {
        return (collectionView.cellForItem(at: indexPath) as? YourCustomCell)?.imageView
      }
    }
    return nil
  }
}

基准测试

显示 1 张图片

CPU 使用率 内存使用率
SwiftyGif 2% 44.6Mb
Gifu 2% 46.3Mb
JellyGif 1% 46.3Mb
JellyGif(优化模式开启) 1% 30.3Mb

显示 10 张图片

CPU 使用率 内存使用率
SwiftyGif 34% 31.7Mb
Gifu 6% 200Mb
JellyGif 6% 200Mb
JellyGif(优化模式开启) 5% 39.1Mb

在 iPhone Xs Max,iOS 13.3.1 和 Xcode 11.3.1 上进行测量

兼容性

  • iOS 10.0+
  • Swift 5.0
  • Xcode 10+