Convert Figma logo to code with AI

Flipboard logoFLAnimatedImage

Performant animated GIF engine for iOS

7,923
1,213
7,923
81

Top Related Projects

9,346

An easy way to add a simple, shimmering effect to any view in an iOS app.

An iOS library to natively render After Effects vector animations

Asynchronous image downloader with cache support as a UIImageView category

Promises for Swift & ObjC.

A lightweight, pure-Swift library for downloading and caching images from the web.

1,762

Image framework for iOS to display/encode/decode animated WebP, APNG, GIF, and more.

Quick Overview

FLAnimatedImage is a performant animated GIF engine for iOS, developed by Flipboard. It offers smooth playback of GIF animations with low memory usage, making it ideal for mobile applications that need to display animated images efficiently.

Pros

  • High performance and low memory footprint
  • Asynchronous GIF loading and decoding
  • Supports progressive loading for large GIFs
  • Compatible with UIImageView for easy integration

Cons

  • Limited to GIF format, doesn't support other animation formats
  • Requires manual integration (not available through CocoaPods or Carthage)
  • May have compatibility issues with newer iOS versions if not regularly updated
  • Limited customization options for animation playback

Code Examples

  1. Creating an FLAnimatedImage from a file:
NSData *data = [NSData dataWithContentsOfFile:@"animated.gif"];
FLAnimatedImage *image = [FLAnimatedImage animatedImageWithGIFData:data];
FLAnimatedImageView *imageView = [[FLAnimatedImageView alloc] init];
imageView.animatedImage = image;
[self.view addSubview:imageView];
  1. Loading a GIF from a URL:
NSURL *url = [NSURL URLWithString:@"https://example.com/animated.gif"];
NSURLSession *session = [NSURLSession sharedSession];
[[session dataTaskWithURL:url completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {
    FLAnimatedImage *image = [FLAnimatedImage animatedImageWithGIFData:data];
    dispatch_async(dispatch_get_main_queue(), ^{
        self.imageView.animatedImage = image;
    });
}] resume];
  1. Controlling playback:
FLAnimatedImageView *imageView = [[FLAnimatedImageView alloc] init];
// Pause animation
imageView.playbackPaused = YES;
// Resume animation
imageView.playbackPaused = NO;
// Set loop count (0 for infinite)
imageView.loopCompletionBlock = ^(NSUInteger loopCountRemaining) {
    if (loopCountRemaining == 0) {
        NSLog(@"Animation finished");
    }
};

Getting Started

  1. Clone the repository:

    git clone https://github.com/Flipboard/FLAnimatedImage.git
    
  2. Add the following files to your Xcode project:

    • FLAnimatedImage.h
    • FLAnimatedImage.m
    • FLAnimatedImageView.h
    • FLAnimatedImageView.m
  3. Import the header in your source file:

    #import "FLAnimatedImage.h"
    
  4. Create an FLAnimatedImageView and set its animatedImage property:

    NSData *data = [NSData dataWithContentsOfFile:@"animated.gif"];
    FLAnimatedImage *image = [FLAnimatedImage animatedImageWithGIFData:data];
    FLAnimatedImageView *imageView = [[FLAnimatedImageView alloc] init];
    imageView.animatedImage = image;
    [self.view addSubview:imageView];
    

Competitor Comparisons

9,346

An easy way to add a simple, shimmering effect to any view in an iOS app.

Pros of Shimmer

  • Lightweight and easy to implement
  • Provides a subtle, eye-catching animation effect
  • Can be applied to various UI elements

Cons of Shimmer

  • Limited to a specific shimmering effect
  • Less versatile for complex animations
  • Requires more manual control for timing and duration

Code Comparison

FLAnimatedImage:

FLAnimatedImage *image = [FLAnimatedImage animatedImageWithGIFData:gifData];
FLAnimatedImageView *imageView = [[FLAnimatedImageView alloc] init];
imageView.animatedImage = image;

Shimmer:

FBShimmeringView *shimmeringView = [[FBShimmeringView alloc] init];
shimmeringView.contentView = imageView;
shimmeringView.shimmering = YES;

Summary

FLAnimatedImage is specifically designed for efficient GIF rendering and playback, offering better performance and memory management for animated images. It's ideal for apps that heavily rely on GIF animations.

Shimmer, on the other hand, provides a simple shimmering effect that can be applied to any view. It's more suitable for creating subtle loading indicators or highlighting specific UI elements.

While FLAnimatedImage is more focused on GIF handling, Shimmer offers a broader application for adding visual interest to various parts of an app's interface. The choice between the two depends on the specific animation needs of your project.

An iOS library to natively render After Effects vector animations

Pros of Lottie-iOS

  • Supports complex vector animations created in Adobe After Effects
  • Offers a wide range of customization options and dynamic properties
  • Provides cross-platform compatibility (iOS, Android, Web)

Cons of Lottie-iOS

  • Larger file size and potentially higher memory usage
  • Steeper learning curve for creating and implementing animations
  • May have performance issues with very complex animations

Code Comparison

FLAnimatedImage:

FLAnimatedImage *image = [FLAnimatedImage animatedImageWithGIFData:gifData];
FLAnimatedImageView *imageView = [[FLAnimatedImageView alloc] init];
imageView.animatedImage = image;
[self.view addSubview:imageView];

Lottie-iOS:

let animationView = AnimationView(name: "animation")
animationView.frame = self.view.bounds
animationView.contentMode = .scaleAspectFit
animationView.loopMode = .loop
self.view.addSubview(animationView)
animationView.play()

Summary

FLAnimatedImage is focused on efficient GIF rendering, while Lottie-iOS offers more complex vector animations. FLAnimatedImage is simpler to use and may have better performance for basic animations, but Lottie-iOS provides greater flexibility and cross-platform support. The choice between the two depends on the specific animation requirements and complexity of the project.

Asynchronous image downloader with cache support as a UIImageView category

Pros of SDWebImage

  • Broader functionality: Supports various image formats, including GIFs, WebP, and HEIC
  • Extensive caching system: Efficient memory and disk caching for improved performance
  • Active development: Regular updates and a large community of contributors

Cons of SDWebImage

  • Larger library size: More comprehensive features result in a larger footprint
  • Steeper learning curve: More complex API due to its extensive functionality

Code Comparison

SDWebImage:

let imageView = UIImageView()
imageView.sd_setImage(with: URL(string: "https://example.com/image.gif"))

FLAnimatedImage:

let animatedImage = FLAnimatedImage(gifData: gifData)
let imageView = FLAnimatedImageView()
imageView.animatedImage = animatedImage

Key Differences

  • FLAnimatedImage focuses specifically on GIF handling and display
  • SDWebImage offers a more comprehensive solution for image loading and caching
  • FLAnimatedImage provides finer control over GIF playback and performance
  • SDWebImage integrates more easily with various image sources (network, local, etc.)

Both libraries have their strengths, with FLAnimatedImage excelling in GIF-specific scenarios and SDWebImage offering a more versatile solution for general image handling needs.

Promises for Swift & ObjC.

Pros of PromiseKit

  • Provides a robust asynchronous programming model for Swift and Objective-C
  • Simplifies complex asynchronous operations and error handling
  • Extensive ecosystem with many extensions for popular libraries

Cons of PromiseKit

  • Steeper learning curve for developers new to promise-based programming
  • May introduce additional overhead for simple asynchronous tasks
  • Requires careful management to avoid retain cycles and memory leaks

Code Comparison

FLAnimatedImage:

FLAnimatedImage *image = [FLAnimatedImage animatedImageWithGIFData:gifData];
FLAnimatedImageView *imageView = [[FLAnimatedImageView alloc] init];
imageView.animatedImage = image;

PromiseKit:

firstly {
    URLSession.shared.dataTask(.promise, with: url)
}.then { data in
    JSONDecoder().decode(MyModel.self, from: data)
}.done { model in
    // Use the model
}.catch { error in
    // Handle errors
}

While FLAnimatedImage focuses on efficient GIF rendering, PromiseKit provides a framework for managing asynchronous operations. FLAnimatedImage is more specialized, while PromiseKit offers a general-purpose solution for handling complex asynchronous workflows. The choice between them depends on the specific needs of your project.

A lightweight, pure-Swift library for downloading and caching images from the web.

Pros of Kingfisher

  • Supports a wider range of image formats, including JPEG, PNG, GIF, WebP, and more
  • Offers advanced features like image processing, caching, and prefetching
  • Actively maintained with frequent updates and a large community

Cons of Kingfisher

  • Larger library size, which may impact app size and performance
  • Steeper learning curve due to more complex API and features
  • May be overkill for projects that only need basic GIF support

Code Comparison

FLAnimatedImage:

let animatedImage = FLAnimatedImage(animatedGIFData: gifData)
let imageView = FLAnimatedImageView()
imageView.animatedImage = animatedImage

Kingfisher:

let url = URL(string: "https://example.com/image.gif")
imageView.kf.setImage(with: url)

Summary

Kingfisher is a more comprehensive image loading library with support for various formats and advanced features, while FLAnimatedImage focuses specifically on GIF handling. Kingfisher offers greater flexibility but may be more complex, whereas FLAnimatedImage provides a simpler solution for projects primarily dealing with GIFs.

1,762

Image framework for iOS to display/encode/decode animated WebP, APNG, GIF, and more.

Pros of YYImage

  • Supports a wider range of image formats, including APNG, WebP, and GIF
  • Offers more advanced features like image editing and progressive loading
  • Provides better performance for large animated images

Cons of YYImage

  • More complex API, which may increase the learning curve
  • Larger library size due to additional features
  • Less focused on animated GIFs compared to FLAnimatedImage

Code Comparison

YYImage:

YYImage *image = [YYImage imageNamed:@"animation.gif"];
YYAnimatedImageView *imageView = [[YYAnimatedImageView alloc] initWithImage:image];
[self.view addSubview:imageView];

FLAnimatedImage:

FLAnimatedImage *image = [FLAnimatedImage animatedImageWithGIFData:[NSData dataWithContentsOfFile:@"animation.gif"]];
FLAnimatedImageView *imageView = [[FLAnimatedImageView alloc] init];
imageView.animatedImage = image;
[self.view addSubview:imageView];

Both libraries provide similar functionality for displaying animated GIFs, but YYImage offers a more comprehensive set of features for image handling. FLAnimatedImage is more focused on efficient GIF rendering, while YYImage supports a broader range of formats and advanced image processing capabilities. The choice between the two depends on the specific requirements of your project and the importance of additional features versus a more streamlined, GIF-focused solution.

Convert Figma logo designs to code with AI

Visual Copilot

Introducing Visual Copilot: A new AI model to turn Figma designs to high quality code using your components.

Try Visual Copilot

README

FLAnimatedImage · GitHub license PRs Welcome

FLAnimatedImage is a performant animated GIF engine for iOS:

  • Plays multiple GIFs simultaneously with a playback speed comparable to desktop browsers
  • Honors variable frame delays
  • Behaves gracefully under memory pressure
  • Eliminates delays or blocking during the first playback loop
  • Interprets the frame delays of fast GIFs the same way modern browsers do

It's a well-tested component that powers all GIFs in Flipboard. To understand its behavior it comes with an interactive demo:

Flipboard playing multiple GIFs

Who is this for?

  • Apps that don't support animated GIFs yet
  • Apps that already support animated GIFs but want a higher performance solution
  • People who want to tinker with the code (the corresponding blog post is a great place to start; also see the To Do section below)

Installation & Usage

FLAnimatedImage is a well-encapsulated drop-in component. Simply replace your UIImageView instances with instances of FLAnimatedImageView to get animated GIF support. There is no central cache or state to manage.

If using CocoaPods, the quickest way to try it out is to type this on the command line:

$ pod try FLAnimatedImage

To add it to your app, copy the two classes FLAnimatedImage.h/.m and FLAnimatedImageView.h/.m into your Xcode project or add via CocoaPods by adding this to your Podfile:

pod 'FLAnimatedImage', '~> 1.0'

If using Carthage, add the following line into your Cartfile

github "Flipboard/FLAnimatedImage"

If using Swift Package Manager, add the following to your Package.swift or add via XCode:

dependencies: [
    .package(url: "https://github.com/Flipboard/FLAnimatedImage.git", .upToNextMajor(from: "1.0.16"))
],
targets: [
    .target(name: "TestProject", dependencies: ["FLAnimatedImage""])
]

In your code, #import "FLAnimatedImage.h", create an image from an animated GIF, and setup the image view to display it:

FLAnimatedImage *image = [FLAnimatedImage animatedImageWithGIFData:[NSData dataWithContentsOfURL:[NSURL URLWithString:@"https://upload.wikimedia.org/wikipedia/commons/2/2c/Rotating_earth_%28large%29.gif"]]];
FLAnimatedImageView *imageView = [[FLAnimatedImageView alloc] init];
imageView.animatedImage = image;
imageView.frame = CGRectMake(0.0, 0.0, 100.0, 100.0);
[self.view addSubview:imageView];

It's flexible to integrate in your custom image loading stack and backwards compatible to iOS 9.

It uses ARC and the Apple frameworks QuartzCore, ImageIO, MobileCoreServices, and CoreGraphics.

It is capable of fine-grained logging. A block can be set on FLAnimatedImage that's invoked when logging occurs with various log levels via the +setLogBlock:logLevel: method. For example:

// Set up FLAnimatedImage logging.
[FLAnimatedImage setLogBlock:^(NSString *logString, FLLogLevel logLevel) {
    // Using NSLog
    NSLog(@"%@", logString);

    // ...or CocoaLumberjackLogger only logging warnings and errors
    if (logLevel == FLLogLevelError) {
        DDLogError(@"%@", logString);
    } else if (logLevel == FLLogLevelWarn) {
        DDLogWarn(@"%@", logString);
    }
} logLevel:FLLogLevelWarn];

Since FLAnimatedImage is licensed under MIT, it's compatible with the terms of using it for any app on the App Store.

Release process

  1. Bump version in FLAnimatedImage.podspec, update CHANGES, and commit.
  2. Tag commit with > git tag -a <VERSION> -m "<VERSION>" and > git push --tags.
  3. Submit Podspec to Trunk with > pod trunk push FLAnimatedImage.podspec (ensure you're auth'ed).

To Do

  • Support other animated image formats such as APNG or WebP (WebP support implemented here)
  • Integration into network libraries and image caches
  • Investigate whether FLAnimatedImage should become a UIImage subclass
  • Smarter buffering
  • Bring demo app to iPhone

This code has successfully shipped to many people as is, but please do come with your questions, issues and pull requests!

Select apps using FLAnimatedImage

(alphabetically)

If you're using FLAnimatedImage in your app, please open a PR to add it to this list!