iOS 3D Touch – Peek and Pop

Filed Under: iOS

In this tutorial, we’ll be discussing and implementing the 3D Touch functionality in our iOS Application.

Peek and Pop

Peek and Pop is a functionality that is available in iPhone 6s and above. It occurs when a user presses deeply onto the screen.
we can show a preview of the next screen in a small window along with Quick Actions too.
It gives the feeling of a 3D touch.

Instead of going onto the next screen, you can quickly preview the content using 3D Touch.
Pressing Hard shows you the preview.
Pressing Harder would show the entire screen.

To do it automatically using Storyboard, we can always select the option “Preview & Commit Segues” in the attributes inspector on the segue.

In order to use Peek and Pop feature, UIViewControllerPreviewingDelegate protocol must be added to the ViewController class and the delegate methods need to be implemented.

  • previewingContext(_ previewingContext: UIViewControllerPreviewing, viewControllerForLocation location: CGPoint)
  • previewingContext(_ previewingContext: UIViewControllerPreviewing, commit viewControllerToCommit: UIViewController)

Learn by example!

In the next section, we’ll learn by implementing Peek and Pop on a UITableView in our iOS Application.

First the storyboard!

Project Storyboard

ios peek pop storyboard 1

Let’s embed the First View Controller in a NavigationController.

ios peek pop storyboard 2

Connect the IBOutlet for all the elements to their respective View Controller.

Code

In order to implement Peek and Pop, we need to first register the view on which the 3D interaction is enabled.
We can add the following statement in the viewDidLoad method for that:


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

The code for the ViewController.swift file is given below:


import UIKit

class ViewController: UIViewController, UITableViewDelegate, UITableViewDataSource, UIViewControllerPreviewingDelegate {
    

    @IBOutlet weak var myTableView: UITableView!
    
    var myArray = ["apple","windows","amazon"]
    
    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view, typically from a nib.
        
        if( traitCollection.forceTouchCapability == .available){
            registerForPreviewing(with: self, sourceView: myTableView)
        }
        
        myTableView.delegate = self
        myTableView.dataSource = self
    }
 
    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return myArray.count
    }
    
    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath)
        cell.textLabel?.text = myArray[indexPath.row]
        return cell
    }
    
    func previewingContext(_ previewingContext: UIViewControllerPreviewing, viewControllerForLocation location: CGPoint) -> UIViewController? {
        guard let indexPath = myTableView?.indexPathForRow(at: location) else { return nil }
        
        guard let cell = myTableView?.cellForRow(at: indexPath) else { return nil }
        
        guard let detailVC = storyboard?.instantiateViewController(withIdentifier: "DetailViewController") as? DetailViewController else { return nil }
        
        let text = myArray[indexPath.row]
        detailVC.string = text
        
        detailVC.preferredContentSize = CGSize(width: 0.0, height: 300)
        
        previewingContext.sourceRect = cell.frame
        
        return detailVC
    }
    
    var name: String?
    
    func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
        
        name = myArray[indexPath.row]
        
        let secondViewController = self.storyboard?.instantiateViewController(withIdentifier: "DetailViewController") as! DetailViewController
        
        secondViewController.string = name
        
        self.navigationController?.pushViewController(secondViewController, animated: true)
        
        tableView.deselectRow(at: indexPath, animated: true)
    }
    
    func previewingContext(_ previewingContext: UIViewControllerPreviewing, commit viewControllerToCommit: UIViewController) {
        show(viewControllerToCommit, sender: self)
    }

}

We populate the UITableView with an array of strings.
In the previewing protocol delegate method, we launch the detail view controller in a small window.
In the didSelectRow method of the UITableView protocols, we directly take the user to the DetailsViewController alongwith passing the data.

The code for the DetailViewController.swift is given below:


import UIKit

class DetailViewController : UIViewController{
    
    @IBOutlet weak var myLabel: UILabel!
    
    var string: String?
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
        if let string = string{
            myLabel.text = string
        }
    }
}

The output of the above application in action is given below:

ios peek pop output 1

Using Preview Actions

To show Preview Actions, you need to add the following code in the ViewController that is previewed.
It is DetailsViewController in our case.


import UIKit

class DetailViewController : UIViewController{
    
    @IBOutlet weak var myLabel: UILabel!
    
    var string: String?
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
        if let string = string{
            myLabel.text = string
        }
    }
    
    override var previewActionItems : [UIPreviewActionItem] {
        
        let likeAction = UIPreviewAction(title: "Option 1", style: .default) { (action, viewController) -> Void in
            print("You clicked this")
        }
        
        let deleteAction = UIPreviewAction(title: "Option 2", style: .destructive) { (action, viewController) -> Void in
            print("You clicked this too")
        }
        
        return [likeAction, deleteAction]
        
    }
}

The output of the application with the above actions is given below:

ios peek pop output 2

This brings an end to this tutorial. You can download the project from the link below:

Leave a Reply

Your email address will not be published. Required fields are marked *

close
Generic selectors
Exact matches only
Search in title
Search in content
Search in posts
Search in pages