The official Pinterest engineering blog.

At WWDC this past June, Apple unveiled iOS7 and redefined the platform with a new visual design, including changes to UIKit and a set of new APIs. A team of four Pinterest engineers collaborated with the design team to rebuild the Pinterest iOS app with easier navigation, custom transitions, and more ways to discover related Pins through gestures, such as swiping.

image

With more than ¾ of all Pinterest usage occurring on mobile, it was important that the 3.0 update responded to Pinner requests for simpler, faster ways to engage with more Pins, and to provide an overall improved experience. Our main challenge was to reimagine the app while maintaining the aesthetics of our brand. We focused on three areas:

  • Migrating to UICollectionView and dropping iOS5 support
  • Adopting newer iOS7 APIs including UIViewController Transitions, Background Fetching, and UIKit Dynamics.
  • Building a new gestural interface

Embracing UICollectionView

At the core of the Pinterest app you’ll find UICollectionView. Before we dropped iOS5 support, we managed our own UIScrollView subclass for building grids. It was modeled after UITableView and handled all of the cell reuse and layout. Now that we’ve moved to support iOS6+, we’ve migrated our app over to UICollectionView, which all of the main views in the app use. We wrote a UICollectionViewLayout subclass to manage the layout of grid, which supports multiple sections, header/footer views, and floating headers.

image

image

Adopting new iOS7 APIs

iOS7 provides new powerful view controller transitioning APIs. We used these when tapping on a Pin from the grid to go into closeup:

image

We wanted to provide a transition that helped the user understand where they were at all times, and to help enforce that they can swipe left and right to explore more Pins. To do this, we used UINavigationControllerDelegate’s animationControllerForOperation method to provide a UIViewControllerAnimatedTransitioning object to perform the transition:

- (id )navigationController:(UINavigationController *)navigationController
                                   animationControllerForOperation:(UINavigationControllerOperation)operation
                                                fromViewController:(UIViewController *)fromVC
                                                  toViewController:(UIViewController *)toVC {
    if (operation == UINavigationControllerOperationPush && [toVC isKindOfClass:[CBLPinViewController class]]) {
        return [[CBLPinViewTransition alloc] init];
    } else if (operation == UINavigationControllerOperationPop && [fromVC isKindOfClass:[CBLPinViewController class]]) {
        return [[CBLGridViewTransition alloc] init];
    }
    return nil;
}

On iOS6, we fallback to the default UINavigationController slide transition.

We also adopted the new background multitasking modes on iOS7 to surface newer content without requiring Pinners to manually refresh their home feeds. iOS7 provides two new modes for background multitasking, by either having the app fetch new content, or be notified via silent notification. We implemented the “fetch” background mode.

Apple states that when the OS permits your app to download new content, it will launch or resume it in the background and provide it with a small amount of time to do work. When this happens, the system will call UIApplicationDelegate’s performFetchWithCompletion. We offload the fetching logic to our rootViewController who then calls the completion block with either UIBackgroundFetchResultNewData, UIBackgroundFetchResultNoData or UIBackgroundFetchResultFailed.

- (void)application:(UIApplication *)application performFetchWithCompletionHandler:(void (^)(UIBackgroundFetchResult))completionHandler
{
    [self.rootViewController performBackgroundFetchWithCompletion:completionHandler];
}

If new Pins are available, the home feed view is updated to indicate there are new Pins. Since iOS7 also allows you to update the screenshot for your app in the multitasking view, this was a great opportunity to grab the user’s attention to open up the app:

image

New Gestural Design

With our 3.0 release, we wanted to completely rethink how gestures were used. Earlier this year we presented iOS Pinners with an animated “contextual menu” when long pressing on a Pin to make it faster to Pin, like and send inline from the grid. We plan on adding this menu to boards and users in the future.

image

All of the animations and interactions for the menu are driven by a combination of CADisplayLink and Core Animation.

We wanted to teach Pinners another gestural interface that was engaging yet easy to understand. We looked at the data to better understand how Pinners were navigating the app, and we noticed a few things:

  • Pinners spent a lot of time in closeup view of a Pin where they could see a larger image and more metadata
  • Many performed core actions, such as Pinning, from closeup
  • They were often hitting the back button to get back to the grid to tap on the next Pin in the feed

We determined that adding the ability for Pinners to swipe left and right to discover more Pins would be simpler, faster and a more engaging experience.

image

This view was built using a horizontal UICollectionView, with UIScrollViews for each cell. Inside the scroll view exists another UICollectionView to present the related pins below.

More mobile to come!

In re-architecting the app, the team has laid the foundation to continue innovating on mobile, as many of these changes will be seen soon on iPad. As mobile is the leading platform for Pinterest, the team is focused on providing the best experience possible for Pinners on the go, regardless of the device they’re using. There are a lot of exciting projects we have planned for next year—if you’re interested in joining us, check out our careers page!

Steven Ramkumar is a software engineer at Pinterest and works on Mobile.