Go to file
Reda Lemeden 9ecb4b63e1 Clarify that UIImageView is not animatable as-is 2016-10-08 10:32:53 +02:00
Demo Add empty view controller 2016-10-06 23:59:14 +02:00
Gifu.xcodeproj Reorganize project using Synx 2016-10-06 23:59:14 +02:00
Gifu.xcworkspace Add Swift 2.0 support 2015-10-22 19:14:35 +02:00
GifuTests Reorganize project using Synx 2016-10-06 23:59:14 +02:00
Source Update README and check-in docs 2016-10-06 23:59:14 +02:00
Supporting Files Update README and check-in docs 2016-10-06 23:59:14 +02:00
bin Update source to Swift 3.0 and Xcode 8 2016-10-06 23:59:14 +02:00
docs Update README and check-in docs 2016-10-06 23:59:14 +02:00
.gitignore Update README and check-in docs 2016-10-06 23:59:14 +02:00
.jazzy.yaml Update jazzy config 2016-05-28 21:46:29 +02:00
.swift-version Add swift-version 2016-10-07 22:59:40 +02:00
.travis.yml Update source to Swift 3.0 and Xcode 8 2016-10-06 23:59:14 +02:00
Gifu.podspec Add swift-version 2016-10-07 22:59:40 +02:00
LICENSE Update License 2016-01-20 12:29:26 +00:00
README.md Clarify that UIImageView is not animatable as-is 2016-10-08 10:32:53 +02:00
header.gif Use smaller logo 2016-10-07 00:15:59 +02:00

README.md

Logo

GitHub release Travis Carthage compatible Join the chat at https://gitter.im/kaishin/gifu Swift 3.0.x platforms

Gifu adds protocol-based, performance-aware animated GIF support to UIKit. (It's also a prefecture in Japan).

Swift 2.3 support is on the swift2.3 branch. This branch will not be getting any future updates.

Install

Carthage

  • Add the following to your Cartfile: github "kaishin/Gifu"
  • Then run carthage update
  • Follow the current instructions in Carthage's README for up to date installation instructions.

CocoaPods

  • Add the following to your Podfile: pod 'Gifu'
  • You will also need to make sure you're opting into using frameworks: use_frameworks!
  • Then run pod install with CocoaPods 0.36 or newer.

How It Works

Gifu does not force you to use a specific subclass UIImageView. 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.

The 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.

The figure below summarizes how this works in practice. Given an image containing 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):

Usage

There are two options that should cover any situation:

  • Use the built-in GIFImageView subclass.
  • Make any class conform to GIFAnimatable. Subclassing UIImageView is the easiest since you get most of the required properties for free.

GIFImageView

A subclass of UIImageView that conforms to GIFAnimatable. You can use this class as-is or subclass it for further customization (not recommended).

GIFAnimatable

The bread and butter of Gifu. Through protocol extensions, GIFAnimatable exposes all the APIs of the library, and with very little boilerplate, any UIImageView subclass can conform to it.

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

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

That's it. Now MyImageView is fully GIF-compatible, and any of these methods can be called on it:

  • prepareForAnimation(withGIFNamed:) and prepareForAnimation(withGIFData:) to prepare the animator property for animation.
  • startAnimatingGIF() and stopAnimatingGIF() to control the animation.
  • animate(withGIFNamed:) and animate(withGIFData:) to prepare for animation and start animating immediately.
  • frameCount, isAnimatingGIF, and activeFrame to inspect the GIF view.
  • prepareForReuse() to free up resources.
  • updateImageIfNeeded() to update the image property if necessary.

This approach is especially powerful when you want to combine the functionality of different image libraries.

class MyImageView: OtherImageClass, GIFAnimatable {}

Keep in mind that you need to have control over the class implementing GIFAnimatable since you cannot add the stored Animator property in an extension.

Examples

The simplest way to get started is initializing a GIFAnimatable class in code or in a storyboard, then calling animate(:) on it.

let imageView = GIFImageView(frame: CGRect(x: 0, y: 0, width: 200, height: 100))
imageView.animate(withGIFNamed: "mugen")

You can also prepare for the animation when the view loads and only start animating after a user interaction.

// In your view controller..

override func viewDidLoad() {
  super.viewDidLoad()
  imageView.prepareForAnimation(withGIFNamed: "mugen")
}

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

If you are using a GIFAnimatable class in a table or collection view, you can call the prepareForReuse() method in your cell subclass:

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

Demo App

Clone or download the repository and open Gifu.xcworkspace to check out the demo app.

Documentation

See the full API documentation.

Compatibility

  • iOS 9.0+
  • Swift 3.0
  • Xcode 8.0

License

See LICENSE.