Blog

Implementing 3D Touch into Find a Film Fast

Date

21st January 2020

Read

5 min

Creator

Dale Jones

This item was originally written by Rob Sammons.


With the introduction of the movie app Find a Film Fast‚ a fast and easy way to get movie recommendations‚ we had the opportunity to implement 3D Touch in two different ways. Home screen actions‚ quick access to functions of the app and ‘Peek and Pop’ to view content of movies and perform actions.

Home screen actions

We use dynamic home screen actions to provide support for the “Go” button‚ which triggers the algorithm and to quickly access movie search. Using dynamic home screen actions means that we can display relevant content‚ depending on whether a user is logged in or not. A user who hasn’t logged in will see a login on their 3D Touch icon instead. Dynamic actions can be created using the following code:

let title = NSLocalizedString(“shortcutLoginTitle”‚ comment: “”)

let subtitle = NSLocalizedString(“shortcutLoginTitle”‚ comment: “”)

let type = NSBundle.mainBundle().bundleIdentifier! + “.Login”

let icon = UIApplicationShortcutIcon(type: .Add)

let dynamicShortcutLogin = UIApplicationShortcutItem(type: type‚ localizedTitle: title‚ localizedSubtitle: subtitle‚ icon: icon‚ userInfo: nil)

UIApplication.sharedApplication().shortcutItems = [dynamicShortcutLogin]

We set these when the users first lands within the app and it checks their logged in status‚ otherwise we set the go and search button actions. Note that dynamic actions will only appear when a user has first started using the app‚ so on first install this isn’t implemented. 

Peek and Pop 

[object Object]

One of the more exciting 3D Touch features is Peek and Pop‚ which allows you to push on a piece of content and view more context or perform more actions. Whilst most apps have implemented home screen actions‚ very few have implemented Peek and Pop. For the majority of apps this is a very simple task. Find A Film Fast allows users to push on a movie  to reveal larger movie art‚ movie info and perform actions for rating. 

First you must register for UIViewControllerPreviewingDelegate‚ Apple provides this function specifically for 3D Touch. You must give the delegate a source view; in this case we have used a collection view as this is where we display the movies.

override func traitCollectionDidChange(previousTraitCollection: UITraitCollection?) {

         if #available(iOS 9.0‚ *) {

             if( traitCollection.forceTouchCapability ==   .Available){

                  registerForPreviewingWithDelegate(self‚    sourceView: self.collectionView)

              }

          } else {

             // Fallback on earlier versions

         }

    } 

[object Object]

To get the best look for 3D Touch you should give the previewing context a sourceRect‚ which defines the frame that can be added. As we are using storyboards‚ we instantiate our movie controller and provide the data that is needed to display this screen. Finally the preferred content size can be used to define the size‚ in this case a width of 0 sets it to the largest it can be on each of the screen sizes‚ this depends on the content you want to display. Instagram uses this to display a small portion of a profile screen.

     func previewingContext(previewingContext: UIViewControllerPreviewing‚ viewControllerForLocation location: CGPoint) -> UIViewController? {

          if let indexPath = self.collectionView.indexPathForItemAtPoint(location)‚ cellAttributes = collectionView.layoutAttributesForItemAtIndexPath(indexPath) {

              previewingContext.sourceRect = cellAttributes.frame

              guard let detailVC = storyboard?.instantiateViewControllerWithIdentifier("SCMovieProfileViewController") as? SCMovieProfileViewController else { return nil }

              self.selectedMovie = self.movieSearchItems![indexPath.row]

              detailVC.selectedMovie = self.selectedMovie detailVC.preferredContentSize = CGSize(width: 0.0‚ height: 650) return detailVC

        }

                   return nil   

           }      

           func previewingContext(previewingContext: UIViewControllerPreviewing‚ commitViewController viewControllerToCommit: UIViewController) {

                    showDetailViewController(viewControllerToCommit‚ sender: self)

            }

Finally‚ to provide the pop functionality‚ you commit the view controller using a push or showDetail method. 

func previewingContext(previewingContext: UIViewControllerPreviewing‚ commitViewController viewControllerToCommit: UIViewController) {

        showDetailViewController(viewControllerToCommit‚ sender: self)

     } 

[object Object]

To provide actions you must put these on the view controller that you are wanting to peek into. Using the previewActionItems function you can return as many preview actions as you like‚ as well as providing styles and actions. As mentioned we use these for ratings. 

override func previewActionItems() -> [UIPreviewActionItem] {

        let meh = UIPreviewAction(title: "Meh"‚ style: .Destructive) { (action‚ viewController) in  self.rateMovie(SCMovieRequest.Rating.MEH)

        } let like = UIPreviewAction(title: "Like"‚ style: .Default) { (action‚ viewController) in self.rateMovie(SCMovieRequest.Rating.LIKE)

        } let love = UIPreviewAction(title: "Love"‚ style: .Default) { (action‚ viewController) in  self.rateMovie(SCMovieRequest.Rating.LOVE)

        }

        return [meh‚ like‚ love]

     }

It is really easy to implement 3D Touch into apps‚ and With millions of iPhone 6s units now in the wild – with more 3D Touch devices to come this Fall – it’s a great time to implement additional functions for these users.