Logo

Test GitHub release Carthage compatible Swift 5.0 platforms

Gifu 为 UIKit 添加了基于协议、性能感知的动画 GIF 支持。(它也是日本的一个县)。

安装

Swift Package Manager

将以下内容添加到你的 Package.swift 文件中

let package = Package(
    dependencies: [
    .package(url: "https://github.com/kaishin/Gifu.git", from: "3.2.2")
    ],
)

Carthage (已弃用)

CocoaPods (已弃用)

已弃用方法通知:使用 Carthage 和 CocoaPods 的安装方法现已弃用,未来版本将不再支持。 建议使用 Swift Package Manager 将 Gifu 集成到你的项目中。

工作原理

Gifu 不需要使用内置的 GIFImageView 子类。 Animator 类负责繁重的工作,而 GIFAnimatable 协议通过协议扩展将功能公开给符合它的视图类。

Animator 有一个 FrameStore,它只在内存中保留有限数量的帧,从而有效地为动画创建一个缓冲区,而不会消耗所有可用内存。 这种方法使加载大型 GIF 更加资源友好。

下图总结了这在实践中是如何工作的。 给定一个包含 10 帧的图像,Gifu 将加载当前帧(红色),在此示例中缓冲接下来的两个帧(橙色),并清空所有其他帧以释放内存(灰色)。

用法

有两种选择可以涵盖任何情况

GIFAnimatable

Gifu 的核心。 通过协议扩展,GIFAnimatable 公开库的所有 API,只需很少的样板代码,任何类都可以符合它。

class MyImageView: UIImageView, GIFAnimatable {
  public lazy var animator: Animator? = {
    return Animator(withDelegate: self)
  }()

  override public func display(_ layer: CALayer) {
    updateImageIfNeeded()
  }
}

就是这样。 现在 MyImageView 可以访问所有这些方法和属性

此外,你可以使任何类都可以进行 GIF 动画,从 UIView 子类开始

class CustomAnimatedView: UIView, GIFAnimatable {
  public lazy var animator: Animator? = {
    return Animator(withDelegate: self)
  }()

  override public func display(_ layer: CALayer) {
    updateImageIfNeeded()
  }
}

如果你愿意,你还可以使用关联对象使 UIKit 类符合要求

import UIKit
import Gifu

extension UIImageView: GIFAnimatable {
  private struct AssociatedKeys {
    static var AnimatorKey = "gifu.animator.key"
  }

  override open func display(_ layer: CALayer) {
    updateImageIfNeeded()
  }

  public var animator: Animator? {
    get {
      guard let animator = objc_getAssociatedObject(self, &AssociatedKeys.AnimatorKey) as? Animator else {
        let animator = Animator(withDelegate: self)
        self.animator = animator
        return animator
      }

      return animator
    }

    set {
      objc_setAssociatedObject(self, &AssociatedKeys.AnimatorKey, newValue as Animator?, .OBJC_ASSOCIATION_RETAIN_NONATOMIC)
    }
  }
}

示例

入门的最简单方法是在代码或故事板中初始化一个 GIFAnimatable 类,然后在它上面调用 animate(:)

let imageView = GIFImageView(frame: CGRect(x: 0, y: 0, width: 200, height: 100))
imageView.animate(withGIFNamed: "mugen") {
  print("It's animating!")
}

你还可以在视图加载时准备动画,并在用户交互后才开始动画。

// In your view controller..

override func viewDidLoad() {
  super.viewDidLoad()
  imageView.prepareForAnimation(withGIFNamed: "mugen") {
    print("Ready to animate!")
  }
}

@IBAction func toggleAnimation(_ sender: AnyObject) {
  if imageView.isAnimatingGIF {
    imageView.stopAnimatingGIF()
  } else {
    imageView.startAnimatingGIF()
  }
}

如果你在表或集合视图中使用 GIFAnimatable 类,你可以在单元格子类中调用 prepareForReuse() 方法

override func prepareForReuse() {
  super.prepareForReuse()
  imageView.prepareForReuse()
}

演示应用程序

克隆或下载存储库并打开 Demo/Demo.xcworkspace 以查看演示应用程序。

文档

请参阅完整的 API 文档

兼容性

许可证

请参阅 LICENSE。