Skip to content


Switch branches/tags

Name already in use

A tag already exists with the provided branch name. Many Git commands accept both tag and branch names, so creating this branch may cause unexpected behavior. Are you sure you want to create this branch?

Latest commit


Git stats


Failed to load latest commit information.
Latest commit message
Commit time




The BFRImageViewer is a turnkey solution to present images within your iOS app πŸŽ‰!

It features swipe gestures to dismiss, automatic image scaling, zooming and panning, supports multiple images, image types, URL backloading, custom view controller transitions, built in parallax effect, live photos and plays nicely with 3D touch! We use it all over the place in Buffer for iOS :-).

We've got code samples of each feature in the demo app, feel free to take a peek πŸ‘€.


The BFRImageViewer is hosted on CocoaPods and is the recommended way to install it:

pod 'BFRImageViewer'


To get up and running quickly with BFRImageViewer, just initialize it - that's really about it!

//Image source can be an array containing a mix of PHAssets, NSURLs, URL strings, UIImage, PHLivePhoto or BFRBackLoadedImageSource
BFRImageViewController *imageVC = [[BFRImageViewController alloc] initWithImageSource:@[image]];
let imageVC = BFRImageViewController(imageSource: [image])

From there, you'll have every photo automagically loaded up and be able to page between them. If you want some additional context, just fire up the demo project and take a peek πŸ‘Œ!

Custom Transition

If you'd like to use a custom view controller transition, which zooms the selected image into the image viewer, just set up some properties on the dedicated image viewer animator class:

// In viewDidLoad...
self.imageViewAnimator = [BFRImageTransitionAnimator new];

// Later on, when you want to show an image...
self.imageViewAnimator.animatedImageContainer = self.imageView;
self.imageViewAnimator.animatedImage = self.imageView.image;
self.imageViewAnimator.imageOriginFrame = self.imageView.frame;
self.imageViewAnimator.desiredContentMode = self.imageView.contentMode; //Optional

BFRImageViewController *imageVC = [[BFRImageViewController alloc] initWithImageSource:@[self.imageView.image]];
imageVC.transitioningDelegate = self.imageViewAnimator; 

[self presentViewController:imageVC animated:YES completion:nil];

That will give you this effect (excuse the low quality gif πŸ™ˆ):


URL Backloading

Say you've got a thumbnail of an image, but also a URL of the higher fidelity version too. Using URL backloading, you can quickly show the lower resolution image while loading the better version in the background. When it loads - we'll automatically swap it out for you. This allows you to have the best of worlds. You don't need to have users wait for the URL to load, or settle for always viewing the degraded image.

- (void)openImageViewer {
    BFRBackLoadedImageSource *backloadedImage = [[BFRBackLoadedImageSource alloc] initWithInitialImage:[UIImage imageNamed:@"lowResImage"] hiResURL:[NSURL URLWithString:@"cdn.theURl.png"]];
    BFRImageViewController *imageVC = [[BFRImageViewController alloc] initWithImageSource:@[backloadedImage]];
    [self presentViewController:imageVC animated:YES completion:nil];

Going Forward

We regularly maintain this code, and you can also rest assured that it's been battle tested against thousands of users in production πŸ‘. That said, we get things wrong from time to time - so feel free to open an issue for anything you spot!

We are always happy to talk shop, so feel free to give us a shout on Twitter:

Or, hey - why not work on the BFRImageViewer and get paid for it!? We're hiring!


This project uses MIT License.


The BFRImageViewer is a turnkey solution to present images within your iOS app πŸŽ‰!








No packages published