Enhancing the user experience with 3D Touch

One of iOS's lesser-used features is 3D Touch. 3D Touch allows users to perform special interactions with apps by pressing a little bit more firmly on the screen than usual. The iPhone 6s and newer devices support this functionality and it allows for some pretty neat interactions. One of these interactions is called peek and pop.

With peek and pop, a user can 3D Touch an element on the screen and they'll see a preview of the detail page they would see if they had performed a regular tap on the UI element. The following screenshot shows an example of such a preview:

If the user sees a preview like this and they press on their screen a little bit harder, the user commits to seeing this view and they will be taken to the detail page as if they had normally tapped on the contact. Implementing this feature requires only a small amount of effort.

To implement peek and pop, the source view controller must register its intent to display previews. The source view controller must also conform to UIViewControllerPreviewingDelegate so it can provide and commit to the preview view controller.

Before you get to writing the code, there is one change you'll need to make to the storyboard. You currently don't have access to the detail page view controller from code. However, to provide it as a preview view controller, you must be able to provide an instance of ContactDetailViewController.

Open the storyboard file and select the detail view controller. Use the Identity Inspector to set a Storyboard ID on the detail view controller. Use ContactDetailViewController as the value for the Storyboard ID as shown in the following screenshot:

You can use the Storyboard ID to create instances of the detail view controller from code. You'll see how in just a second. First, you'll register ViewController for previewing content. Add the following code to viewDidLoad() on the ViewController:

if traitCollection.forceTouchCapability == .available {
  registerForPreviewing(with: self, sourceView: collectionView)
}

When the current trait collection supports 3D Touch, the view controller is registered for previewing using itself as a delegate. The collection view is used as a source for this interaction since it's the component for which you want to provide previews. The next step is to make ViewController conform to the UIViewControllerPreviewingDelegate protocol. Add the following extension to ViewController.swift to add this conformance:

extension ViewController: UIViewControllerPreviewingDelegate {
  func previewingContext(_ previewingContext: UIViewControllerPreviewing, viewControllerForLocation location: CGPoint) -> UIViewController? {
    guard let tappedIndexPath = collectionView.indexPathForItem(at: location)
      else { return nil }

    let contact = contacts[tappedIndexPath.row]

    guard let viewController = storyboard?.instantiateViewController(withIdentifier:"ContactDetailViewController") as? ContactDetailViewController
      else { return nil }

    viewController.contact = contact
    return viewController
  }

  func previewingContext(_ previewingContext: UIViewControllerPreviewing,
                         commit viewControllerToCommit: UIViewController) {

    navigationController?.show(viewControllerToCommit, sender: self)
  }
}

This extension implements two methods: previewingContext(_:viewControllerForLocation) and previewingContext(_:commit). The first method is responsible for providing the previewed view controller. To provide the correct view controller with the correct contact, this code checks whether the 3D Touch occurred on a collection view cell. Next, a view controller is obtained through the storyboard by using the identifier you configured earlier. Finally, the view controller is assigned a contact and returned for previewing.

The second method is used to commit to seeing the details page. This implementation simply tells the navigation controller to present the view controller that was previewed. When you implement different preview view controllers than the ones you actually want to use when the user commits to navigating to the detail page, you can use the commit method to configure a real detail view controller instead of the preview.

If you run the project on a device that supports 3D Touch, you should be able to apply some force while tapping on a contact to see their previews appear.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset