Gifu 为 UIKit 添加了基于协议、性能感知的动画 GIF 支持。(它也是日本的一个县)。
将以下内容添加到你的 Package.swift
文件中
let package = Package(
dependencies: [
.package(url: "https://github.com/kaishin/Gifu.git", from: "3.2.2")
],
)
github "kaishin/Gifu"
carthage update
pod 'Gifu'
use_frameworks!
pod install
。已弃用方法通知:使用 Carthage 和 CocoaPods 的安装方法现已弃用,未来版本将不再支持。 建议使用 Swift Package Manager 将 Gifu 集成到你的项目中。
Gifu
不需要使用内置的 GIFImageView
子类。 Animator
类负责繁重的工作,而 GIFAnimatable
协议通过协议扩展将功能公开给符合它的视图类。
Animator
有一个 FrameStore
,它只在内存中保留有限数量的帧,从而有效地为动画创建一个缓冲区,而不会消耗所有可用内存。 这种方法使加载大型 GIF 更加资源友好。
下图总结了这在实践中是如何工作的。 给定一个包含 10 帧的图像,Gifu 将加载当前帧(红色),在此示例中缓冲接下来的两个帧(橙色),并清空所有其他帧以释放内存(灰色)。
有两种选择可以涵盖任何情况
GIFImageView
子类。GIFAnimatable
。 实际上,任何 UIView
子类都可以,因为你可以免费获得大多数必需的属性。 为了获得最佳效果,请使你的 UIImageView
子类符合 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
可以访问所有这些方法和属性
prepareForAnimation(withGIFNamed:)
和 prepareForAnimation(withGIFData:)
准备用于动画的 animator 属性。startAnimatingGIF()
和 stopAnimatingGIF()
控制动画。animate(withGIFNamed:)
和 animate(withGIFData:)
准备动画并立即开始动画。frameCount
, isAnimatingGIF
, 和 activeFrame
检查 GIF 视图。prepareForReuse()
释放资源。updateImageIfNeeded()
如果需要,更新图像属性。此外,你可以使任何类都可以进行 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。