[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"project-7000":3},{"id":4,"name":5,"fullName":6,"owner":7,"repo":5,"description":8,"homepage":9,"htmlUrl":10,"language":11,"languages":10,"totalLinesOfCode":10,"stars":12,"forks":13,"watchers":14,"openIssues":15,"contributorsCount":16,"subscribersCount":16,"size":16,"stars1d":16,"stars7d":16,"stars30d":17,"stars90d":16,"forks30d":16,"starsTrendScore":16,"compositeScore":18,"rankGlobal":10,"rankLanguage":10,"license":19,"archived":20,"fork":20,"defaultBranch":21,"hasWiki":20,"hasPages":22,"topics":23,"createdAt":10,"pushedAt":10,"updatedAt":29,"readmeContent":30,"aiSummary":31,"trendingCount":16,"starSnapshotCount":16,"syncStatus":17,"lastSyncTime":32,"discoverSource":33},7000,"Gifu","kaishin\u002FGifu","kaishin","High-performance animated GIF support for iOS in Swift","",null,"Swift",3216,289,44,27,0,2,29.39,"Other",false,"main",true,[24,25,26,27,28],"animation","carthage","cocoapods","gif","swift","2026-06-12 02:01:33","# ![Logo](https:\u002F\u002Fgithub.com\u002Fkaishin\u002FGifu\u002Fraw\u002Fmaster\u002Fheader.gif)\n\n![Test](https:\u002F\u002Fgithub.com\u002Fkaishin\u002FGifu\u002Fworkflows\u002FTest\u002Fbadge.svg)\n[![GitHub release](https:\u002F\u002Fimg.shields.io\u002Fgithub\u002Frelease\u002Fkaishin\u002FGifu.svg)](https:\u002F\u002Fgithub.com\u002Fkaishin\u002FGifu\u002Freleases\u002Flatest) [![Carthage compatible](https:\u002F\u002Fimg.shields.io\u002Fbadge\u002FCarthage-compatible-4BC51D.svg?style=flat)](https:\u002F\u002Fgithub.com\u002FCarthage\u002FCarthage)\n![Swift 5.9+](https:\u002F\u002Fimg.shields.io\u002Fbadge\u002FSwift-5.9+-orange.svg) ![platforms](https:\u002F\u002Fimg.shields.io\u002Fbadge\u002Fplatforms-iOS%20%7C%20tvOS%20%7C%20visionOS-lightgrey.svg)\n\nGifu adds protocol-based, performance-aware animated GIF support to UIKit. (It's also a [prefecture in Japan](https:\u002F\u002Fgoo.gl\u002Fmaps\u002FCCeAc)).\n\n## Install\n\n#### Swift Package Manager\n\nAdd the following to your `Package.swift` file:\n\n```swift\nlet package = Package(\n    dependencies: [\n    .package(url: \"https:\u002F\u002Fgithub.com\u002Fkaishin\u002FGifu.git\", from: \"4.0.0\")\n    ],\n)\n```\n\n## How It Works\n\n`Gifu` does not require using the built-in `GIFImageView` subclass. The `Animator` class does the heavy-lifting, while the `GIFAnimatable` protocol exposes the functionality to the view classes that conform to it, using protocol extensions.\n\nThe `Animator` has a `FrameStore` that only keeps a limited number of frames in-memory, effectively creating a buffer for the animation without consuming all the available memory. This approach makes loading large GIFs a lot more resource-friendly.\n\nThe figure below summarizes how this works in practice. Given an image\ncontaining 10 frames, Gifu will load the current frame (red), buffer the next two frames in this example (orange), and empty up all the other frames to free up memory (gray):\n\n\u003Cimg src=\"https:\u002F\u002Fgithub.com\u002Fkaishin\u002FGifu\u002Fraw\u002Fmaster\u002Fgifu-figure.gif\" width=\"300\" \u002F>\n\n## Usage\n\nThere are two options that should cover any situation:\n\n- Use the built-in `GIFImageView` subclass if you don't need to combine GIF support with another image library.\n- If you need more flexibility and composability, make your class conform to `GIFAnimatable`. In practice, any `UIView` subclass would do, since you get most of the required properties for free. For best results, make your `UIImageView` subclass conform to `GIFAnimatable` to get access to other features such as intrinsic content size.\n\n### GIFAnimatable\n\nThe bread and butter of Gifu. Through protocol extensions, `GIFAnimatable` exposes all the APIs of the library, and with very little boilerplate, any class can conform to it.\n\n```swift\nclass MyImageView: UIImageView, GIFAnimatable {\n  public lazy var animator: Animator? = {\n    return Animator(withDelegate: self)\n  }()\n\n  override public func display(_ layer: CALayer) {\n    updateImageIfNeeded()\n  }\n}\n```\n\nThat's it. Now `MyImageView` has access to all these methods and properties:\n\n- `prepareForAnimation(withGIFNamed:)` and `prepareForAnimation(withGIFData:)` to prepare the animator property for animation.\n- `startAnimatingGIF()` and `stopAnimatingGIF()` to control the animation.\n- `animate(withGIFNamed:)` and `animate(withGIFData:)` to prepare for animation and start animating immediately.\n- `frameCount`, `isAnimatingGIF`, and `activeFrame` to inspect the GIF view.\n- `prepareForReuse()` to free up resources.\n- `updateImageIfNeeded()` to update the image property if necessary.\n\nFurthermore, you can make any class GIF-animatable, starting with `UIView` subclasses:\n\n```swift\nclass CustomAnimatedView: UIView, GIFAnimatable {\n  public lazy var animator: Animator? = {\n    return Animator(withDelegate: self)\n  }()\n\n  override public func display(_ layer: CALayer) {\n    updateImageIfNeeded()\n  }\n}\n```\n\nYou can also make `UIKit` classes conform using associated objects may you wish:\n\n```swift\nimport UIKit\nimport Gifu\n\nextension UIImageView: GIFAnimatable {\n  private struct AssociatedKeys {\n    static var AnimatorKey = \"gifu.animator.key\"\n  }\n\n  override open func display(_ layer: CALayer) {\n    updateImageIfNeeded()\n  }\n\n  public var animator: Animator? {\n    get {\n      guard let animator = objc_getAssociatedObject(self, &AssociatedKeys.AnimatorKey) as? Animator else {\n        let animator = Animator(withDelegate: self)\n        self.animator = animator\n        return animator\n      }\n\n      return animator\n    }\n\n    set {\n      objc_setAssociatedObject(self, &AssociatedKeys.AnimatorKey, newValue as Animator?, .OBJC_ASSOCIATION_RETAIN_NONATOMIC)\n    }\n  }\n}\n```\n\n### Examples\n\nThe simplest way to get started is initializing a `GIFAnimatable` class in code or in a storyboard, then calling `animate(:)` on it.\n\n```swift\nlet imageView = GIFImageView(frame: CGRect(x: 0, y: 0, width: 200, height: 100))\nimageView.animate(withGIFNamed: \"mugen\") {\n  print(\"It's animating!\")\n}\n```\n\nYou can also prepare for the animation when the view loads and only start animating after a user interaction.\n\n```swift\n\u002F\u002F In your view controller..\n\noverride func viewDidLoad() {\n  super.viewDidLoad()\n  imageView.prepareForAnimation(withGIFNamed: \"mugen\") {\n    print(\"Ready to animate!\")\n  }\n}\n\n@IBAction func toggleAnimation(_ sender: AnyObject) {\n  if imageView.isAnimatingGIF {\n    imageView.stopAnimatingGIF()\n  } else {\n    imageView.startAnimatingGIF()\n  }\n}\n```\n\nIf you are using a `GIFAnimatable` class in a table or collection view, you can call the `prepareForReuse()` method in your cell subclass:\n\n```swift\noverride func prepareForReuse() {\n  super.prepareForReuse()\n  imageView.prepareForReuse()\n}\n```\n\n### Demo App\n\nClone or download the repository and open `Demo\u002FDemo.xcworkspace` to check out the demo app.\n\n## Documentation\n\nSee the [full API documentation](http:\u002F\u002Fkaishin.github.io\u002FGifu\u002F).\n\n## Compatibility\n\n- iOS 14.0+\n- tvOS 14.0+\n- visionOS 1.0+\n- Swift 5.9+\n- Xcode 14.0+\n\n## License\n\nSee LICENSE.\n","Gifu 是一个为 iOS 提供高性能 GIF 动画支持的 Swift 库。它通过协议扩展的方式，将动画功能暴露给遵循 `GIFAnimatable` 协议的视图类，核心在于其 `Animator` 类和 `FrameStore` 机制，后者仅在内存中保留有限数量的帧，从而有效缓冲动画并节省资源。Gifu 支持多种安装方式，包括 Swift Package Manager、Carthage 和 CocoaPods，适用于需要在应用中高效展示 GIF 动画的各种场景，无论是简单的图像展示还是与其他图像库结合使用的情况。","2026-06-11 03:10:04","top_language"]