3D Touch - Part II

This is REALLY amazing, it can help developers leverage a lot of entry points into their applications via this technology. This Part II looks at how this can be used to provide the Peek and Pop processes.

Peek and Pop

Surprisingly, this is much easier to setup and use than many of the other features in the iOS SDK. First, the idea behind the peek and the pop.

For those that want to get a better understanding of what can this do, have a look at the Apple Website here to get a better understanding of this functionality.

What is Peek

With a basic look at Peek, it is a way to focus / highlight a single element/item on the screen where the rest of the screen is blurred to provide focus and details about the element that is 3D Touched.

For this example, let us create a simple list of values displayed in a tableView that list out the city names. When pressed slightly, it displays the city name and the population, each having a different background color.

The city structure

First, the structure to hold the cities and an array to hold these cities

struct City {
   let name:String
   let population: String // For now to avoid writing a formatter to display the commas
   let color: UIColor

   init(name:String, population:String, color:UIColor){
     self.name = name
     self.population = population
     self.color = color

let red    = UIColor.redColor()
let orange = UIColor.orangeColor()
let purple = UIColor.purpleColor()
let green  = UIColor.greenColor()

let cities = [
    City(name:"Shanghai",  population:"24,150,000", color: red),
    City(name:"Karachi",   population:"25,500,000", color:green),
    City(name:"Beijing",   population:"21,516,000", color:red),
    City(name:"Tainjin",   population:"14,722,100", color:red),
    City(name:"Istanbul",  population:"14,377,019", color:purple),
    City(name:"Lagos",     population:"13,400,000"),
    City(name:"Tokyo",     population:"13,297,629", color:orange),
    City(name:"Guangzhou", population:"12,700,800", color:red),
    City(name:"Mumbai",    population:"12,655,220"),
    City(name:"Moscow",    population:"12,197,596"),
    City(name:"Dhaka",     population:"12,043,977", color:green),
    City(name:"Cairo",     population:"11,922,949", color:purple),
    City(name:"São Paulo", population:"11,895,893"),
    City(name:"Shenzhen",  population:"10,467,400", color:red),
    City(name:"Seoul",     population:"10,388,055")

Setting the controller up for 3D touch

What happens if you run this application on a device that does not have 3D Touch capabilities? So you need to first check for the capabilities of the device and only if it is supported, do you register the viewController for 3D Touches.

if traitCollection.forceTouchCapability == .Available {
            registerForPreviewingWithDelegate(self, sourceView: tableView)

You can only run this on a device, the simulator does have options on the menu that read as Force Touch Pressure, but that does not work with the phones as yet and works with the Apple Watch simulator.

The viewController must conform to the UIViewControllerPreviewingDelegate protocol and must have these two functions

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

    func previewingContext(
                                   previewingContext: UIViewControllerPreviewing, 
         commitViewController viewControllerToCommit: UIViewController)

Previewing - PEEK

The first function returns a viewController to use to display the item when you press slightly (Peek). On returning a nil (no view controller) the peek is not displayed. You can specify the rectangle for the previewingContext by setting the sourceRect property of the viewController. In case you are working with tableViews of collectionViews where the source rect of the item might change, you can use the parameter viewControllerForLocation which is a CGPoint structure to determine the item at that location.

To get the item in a tableView, you can simply use
let indexPath = tableView.indexPathForRowAtPoint(location)
    let previewingContext.sourceRect = tableView.rectForRowAtIndexPath(indexPath)

and you need to return a UIViewController, you could for testing purposes (NOW) simply return a new UIViewController() everytime

Previewing - POP

If you press harder on the screen, it will make this pop, and pop means displaying the viewController in full screen than how it was displayed earlier. The second function (above) is called to Pop the viewController.

This time we are send a viewController via the commitViewController parameter, and we can show, present or push this viewController.
//presentViewController(viewControllerToCommit, animated: true, completion: nil)
        //showViewController(viewControllerToCommit, sender: self)
        self.navigationController?.pushViewController(viewControllerToCommit, animated: true)

In this example I have used the pushViewController so that the back button and navigation is gotten for free without extra code / effort.

Preview Actions

There is one more functionality that is available with Previewing and that is of action menus. With a peek, you are provided the item on the screen and when you slide it up (the presence of the action items are indicated by the arrow (caret) on the top of the Peek viewController as can be seen in the image.

When you slide this viewController up, you get the action menus displayed below

Note: Though for the lack of an appropriate action menu items, it displays my name. The actions can be such as Share, Delete, eMail, etc. Like the UIAlertController (the AlertBox) actions these actions can be Default or Destructive (displayed with a red text color)


It is actually that simple and cool to use Peek and Pop with the new 3D Touch functionality of the iPhones 6s and 6+s.

The viewController displayed when using Peek can be sized. You can see the full popped view controller with the segment control (in the screenshot) but the same viewController is displayed as a smaller bar in the other screenshots. You can specify or change the contentSize of the viewController to display only certain portions of the viewController.

In essence, the only difference is that the user is not presented with the full viewController that they need to press back thereby allowing a quick look but to display the Peek item, it loads the entire viewController which is similar to loading the viewController to display. So the only efficiency achieved is for the user and that too is only a perception of viewing a preview by not having loaded the entire viewController on screen.


Popular Posts