Top Related Projects
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.
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
- 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];
- 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];
- 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
-
Clone the repository:
git clone https://github.com/Flipboard/FLAnimatedImage.git
-
Add the following files to your Xcode project:
- FLAnimatedImage.h
- FLAnimatedImage.m
- FLAnimatedImageView.h
- FLAnimatedImageView.m
-
Import the header in your source file:
#import "FLAnimatedImage.h"
-
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
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.
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 designs to code with AI
Introducing Visual Copilot: A new AI model to turn Figma designs to high quality code using your components.
Try Visual CopilotREADME
FLAnimatedImage ·
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:
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
- Bump version in
FLAnimatedImage.podspec
, update CHANGES, and commit. - Tag commit with
> git tag -a <VERSION> -m "<VERSION>"
and> git push --tags
. - 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 aUIImage
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)
- Close-up
- Design Shots
- Dropbox
- Dumpert
- Ello
- getGIF
- Gifalicious
- HashPhotos
- LiveBooth
- lWlVl Festival
- Medium
- Slack
- Telegram
- Zip Code Finder
If you're using FLAnimatedImage in your app, please open a PR to add it to this list!
Top Related Projects
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.
Image framework for iOS to display/encode/decode animated WebP, APNG, GIF, and more.
Convert designs to code with AI
Introducing Visual Copilot: A new AI model to turn Figma designs to high quality code using your components.
Try Visual Copilot