How to display Live Photos in a view controller

Live Photo

Live Photos are a brand new kettle of fish: they’re not a UIImage (nor an NSImage), and they’re not a video resource either. To make use of them, Apple gave us a few new classes in iOS 9: PHLivePhoto and PHLivePhotoView. In addition there’s the the PHLivePhotoViewDelegate protocol we can utilise.

Let’s see how to grab a Live Photo from the user’s camera roll, check if it is in fact a Live Photo, and then display it in a Live Photo View. I’ll also describe how to animate the image programmatically.

Prep Work

I’ll start from a single view application template, and my view controller is the main class that’ll do the heavy lifting. Let’s start by importing a few important frameworks and declaring some protocols:

@import Photos;
@import PhotosUI;
@import MobileCoreServices;

@interface ViewController () <UIImagePickerControllerDelegate, UINavigationControllerDelegate, PHLivePhotoViewDelegate>

@property BOOL livePhotoIsAnimating;

There’s no need to explicitly add them to the target in Xcode 7, it’ll “just work” as long as you import Photos, PhotosUI and MobileCoreServices in your class. MobileCoreServices is needed so that the UIImagePickerViewController will work properly – but more on that in a moment.

We want our view controller to conform to three protocols in total: the image picker (which requires the navigation controller protocol), and the photo view delegate protocol. I’ll also add a BOOL property so that I can track if the Live Photo view is currently animating or not.

Picking an image from the Camera Roll

We’ll add button to our storyboard through which we can call a method that lets the user pick an image. Enter the image picker view controller:

- (IBAction)grabLivePhoto:(id)sender {
    // create an image picker
    UIImagePickerController *picker = [[UIImagePickerController alloc]init];
    picker.sourceType = UIImagePickerControllerSourceTypePhotoLibrary;
    picker.allowsEditing = NO;
    picker.delegate = self;
    // make sure we include Live Photos (otherwise we'll only get UIImages)
    NSArray *mediaTypes = @[(NSString *)kUTTypeImage, (NSString *)kUTTypeLivePhoto];
    picker.mediaTypes = mediaTypes;
    // bring up the picker
    [self presentViewController:picker animated:YES completion:nil];

This method first creates the image picker and presents it, waiting for the user to choose an image. One thing we must make sure of here is to set the array of media types: it defaults to standard images, but if we don’t explicitly add the kUTTypeLivePhoto constant, only UIImages will be returned – even if they’re actually Live Photos.

That’s the reason we’ve imported the MobileCoreServices framework by the way: otherwise none of these constants are defined, and Xcode doesn’t know what we mean when we add them.

Displaying a Live Photo

Moving on: once the user has decided on a picture, we need to dismiss the picker and do something with the Live Photo. We do that by conforming to the image picker protocol:

# pragma mark - Image Picker Delegate

- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info {
    // dismiss the picker
    [self dismissViewControllerAnimated:YES completion:nil];
    // if we have a live photo view already, remove it
    if ([self.view viewWithTag:87]) {
        UIView *subview = [self.view viewWithTag:87];
        [subview removeFromSuperview];
    // check if this is a Live Image, otherwise present a warning
    PHLivePhoto *photo = [info objectForKey:UIImagePickerControllerLivePhoto];
    if (!photo) {
        [self notLivePhotoWarning];
    // create a Live Photo View
    PHLivePhotoView *photoView = [[PHLivePhotoView alloc]initWithFrame:self.view.bounds];
    photoView.livePhoto = [info objectForKey:UIImagePickerControllerLivePhoto];
    photoView.contentMode = UIViewContentModeScaleAspectFit;
    photoView.tag = 87;
    // bring up the Live Photo View
    [self.view addSubview:photoView];
    [self.view sendSubviewToBack:photoView];

- (void)imagePickerControllerDidCancel:(UIImagePickerController *)picker {
    [self dismissViewControllerAnimated:YES completion:nil];

This method is a little complex, but breaks down into several easy pieces: in a nutshell, we dismiss the picker view, create a Live Photo View and add it to our current view as a sub view. The rest is needed to make our app play nice (i.e. remove a potentially existing photo view, identified by a random tag, and only display the picture if it is a Live Photo).

A PHLivePhotoView works much like a UIImageView, with the exception that it isn’t available to drag in from interface builder, at least not yet. For now we’ll have to create one in code.

How can we tell that it’s a Live Photo?

The image picker returns an info dictionary with lots of objects at our disposal. One of them is the a PHLivePhoto object, retrievable via the UIPickerControllerLivePhoto key. If this object is nil, we’re not dealing with a Live Photo and assume it’s either a video or a UIImage.

Let’s bring up an alert view with this little method in such an eventuality:

- (void)notLivePhotoWarning {
    // create an alert view
    UIAlertController *alert = [UIAlertController alertControllerWithTitle:@"Not a Live Photo" message:@"Sadly this is a standard image so we can't show it in our Live Photo View. \n\nSorry :-(" preferredStyle:UIAlertControllerStyleAlert];
    // add a single action
    UIAlertAction *action = [UIAlertAction actionWithTitle:@"OK" style:UIAlertActionStyleDefault handler:nil];
    [alert addAction:action];
    // and display it
    [self presentViewController:alert animated:YES completion:nil];

Animating Live Photos

The PHLivePhotoView comes with 3D Touch recognisers built in, so users can animate them just like in the Photos app by deep-pressing down on the screen. This will only work on compatible devices of course, so we may need an option to start (and stop) these animations in code.

We have a choice of two options: a “hint” duration (perhaps half a second), and a “full” duration. The hint is played when you scroll through a bunch of Live Photos in your library, whereas the full duration is played when the user presses down on a Live Photo.

Here’s are two methods that will make those animations happen:

- (IBAction)playHint:(id)sender {
    // grab a reference to our Photo View
    PHLivePhotoView *photoView = [self.view viewWithTag:87];
    // if we're currently animating, ignore this request
    if (self.livePhotoIsAnimating) {
        [photoView stopPlayback];
    // play "hint" animation
    [photoView startPlaybackWithStyle:PHLivePhotoViewPlaybackStyleHint];

- (IBAction)playFullAnimation:(id)sender {
    // grab a reference to our Photo View
    PHLivePhotoView *photoView = [self.view viewWithTag:87];
    // if we're currently animating, ignore this request
    if (self.livePhotoIsAnimating) {
        [photoView stopPlayback];
    // play full animation
    [photoView startPlaybackWithStyle:PHLivePhotoViewPlaybackStyleFull];

Since I gave my Live Photo View a tag earlier (87), it’s easy to retrieve it from the view hierarchy without having to use another property. I’ll make use of the BOOL property I’ve setup earlier and check if an animation is playing already, and if not, I’ll kick it off with the startPlaybackWithStyle method.

The style is either PHLivePhotoViewPlaybackStyleFull or PHLivePhotoViewPlaybackStyleHint.

If you want to stop an animation, call the stopPlayback method (no parameters needed).

Reacting to Animation start and stop

We can use the PHLivePhotoViewDelegate protocol and implement the following two methods that will be called when an animation is about to begin, and when it’s about to stop.

# pragma mark - Live Photo View Delegate

- (void)livePhotoView:(PHLivePhotoView *)livePhotoView willBeginPlaybackWithStyle:(PHLivePhotoViewPlaybackStyle)playbackStyle {
    self.livePhotoIsAnimating = YES;

- (void)livePhotoView:(PHLivePhotoView *)livePhotoView didEndPlaybackWithStyle:(PHLivePhotoViewPlaybackStyle)playbackStyle {
    self.livePhotoIsAnimating = NO;

This step optional of course, but I’m implementing it here because I can keep track of my BOOL accordingly.

Demo Project

Check it out on GitHub:


Further Reading

2 thoughts on “How to display Live Photos in a view controller

  1. Ok now Can you please provide code to save it in document directory to get the .mov filename. Because I want to use live wallpaper somewhere else

    1. Saving a file to the documents directory is easy, extracting a .mov from a Live Photo however is a totally different ball game – and that’s really not what this article is about. I’m afraid I can’t help you there, Aiyub.

Leave a Reply