Home Enhance User Experience by Adding 3D TOUCH to Your iOS APP (Swift)
Post
Cancel

Enhance User Experience by Adding 3D TOUCH to Your iOS APP (Swift)

[Deprecated] Enhance User Experience by Adding 3D TOUCH to Your iOS APP (Swift)

iOS 3D TOUCH Application

[Deprecated] 2020/06/14

3D Touch functionality has been removed in iPhone 11 and later versions; it has been replaced by Haptic Touch, which is implemented differently.

Some time ago, during a break in project development, I explored many interesting iOS features: CoreML, Vision, Notification Service Extension, Notification Content Extension, Today Extension, Core Spotlight, Share Extension, SiriKit (some have been organized into articles, others are coming soon 🤣)

Among them is today’s main feature: 3D Touch

This feature, supported since iOS 9/iPhone 7, only became useful to me after I upgraded from an iPhone 6 to an iPhone 8!

3D Touch can implement two features in an APP, as follows:

1. Preview ViewController Preview Function — [Wedding App](https://itunes.apple.com/tw/app/%E7%B5%90%E5%A9%9A%E5%90%A7-%E4%B8%8D%E6%89%BE%E6%9C%80%E8%B2%B4-%E5%8F%AA%E6%89%BE%E6%9C%80%E5%B0%8D/id1356057329?ls=1&mt=8){:target="_blank"}

  1. Preview ViewController Preview Function — Wedding App

2. 3D Touch Shortcut APP Shortcut Launch Function

  1. 3D Touch Shortcut APP Shortcut Launch Function

The first feature is the most widely used and effective (Facebook: content preview in news feed, Line: sneak peek at messages), while the second feature, APP Shortcut Launch, is less commonly used based on data, so it will be discussed last.

1. Preview ViewController Preview Function:

As shown in the first image above, the ViewController preview function supports:

  • Background blur when 3D Touch is pressed
  • ViewController preview window pops up when 3D Touch is pressed
  • ViewController preview window pops up when 3D Touch is pressed, with an option menu at the bottom when swiped up
  • Return to the window when 3D Touch is released
  • Enter the target ViewController with a harder press after 3D Touch

Here, we will list the code to implement in A: List View and B: Target View separately:

Since there is no way to determine whether the current view is a preview or an actual entry in B, we first create a Protocol to pass values for judgment:

1
2
3
protocol UIViewControllerPreviewable {
    var is3DTouchPreview: Bool { get set }
}

This way, we can make the following judgments in B:

1
2
3
4
5
6
7
8
9
10
class BViewController:UIViewController, UIViewControllerPreviewable {
     var is3DTouchPreview:Bool = false
     override func viewDidLoad() {
     super.viewDidLoad()
     if is3DTouchPreview {
       // If it is a preview window... for example: full screen, hide the toolbar
     } else {
       // Display normally in full mode
   } 
}

A: List window, can be UITableView or UICollectionView:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
class AViewController:UIViewController {
    // Register the View that can 3D Touch
    override func traitCollectionDidChange(_ previousTraitCollection: UITraitCollection?) {
        super.traitCollectionDidChange(previousTraitCollection)
        if traitCollection.forceTouchCapability == .available {
            // TableView:
            registerForPreviewing(with: self, sourceView: self.TableView)
            // CollectionView:
            registerForPreviewing(with: self, sourceView: self.CollectionView)
        }
    }   
}
extension AViewController: UIViewControllerPreviewingDelegate {
    // Handling after 3D Touch is released
    func previewingContext(_ previewingContext: UIViewControllerPreviewing, commit viewControllerToCommit: UIViewController) {
        
        // Now we need to navigate to the page directly, so cancel the preview mode parameter of the ViewController:
        if var viewControllerToCommit = viewControllerToCommit as? UIViewControllerPreviewable {
            viewControllerToCommit.is3DTouchPreview = false
        }
        self.navigationController?.pushViewController(viewControllerToCommit, animated: true)
    }
    
    // Control the position of the 3D Touch Cell, the ViewController to be displayed
    func previewingContext(_ previewingContext: UIViewControllerPreviewing, viewControllerForLocation location: CGPoint) -> UIViewController? {
        
        // Get the current indexPath/cell entity
        // TableView:
        guard let indexPath = TableView.indexPathForRow(at: location), let cell = TableView.cellForRow(at: indexPath) else { return nil }
        // CollectionView:
        guard let indexPath = CollectionView.indexPathForItem(at: location), let cell = CollectionView.cellForItem(at: indexPath) else { return nil }
      
        // The ViewController to be displayed
        let targetViewController = UIStoryboard(name: "StoryboardName", bundle: nil).instantiateViewController(withIdentifier: "ViewControllerIdentifier")
        
        // Retain area when background is blurred (usually the click location), see Figure 1
        previewingContext.sourceRect = cell.frame
        
        // 3D Touch window size, default is adaptive, no need to change
        // To modify, use: targetViewController.preferredContentSize = CGSize(width: 0.0, height: 0.0)
        
        // Inform the previewing ViewController that it is currently in preview mode:
        if var targetViewController = targetViewController as? UIViewControllerPreviewable {
            targetViewController.is3DTouchPreview = true
        }
        
        // Returning nil has no effect
        return nil
    }
}

Note! The registration of the 3D Touch View should be placed in traitCollectionDidChange instead of “viewDidLoad” ( refer to this content )

I encountered many issues regarding where to place it. Some sources on the internet suggest viewDidLoad, while others suggest cellForItem. However, both places may occasionally fail or cause some cells to malfunction.

Figure 1 Background Blur Reserved Area Diagram

Figure 1 Background Blur Reserved Area Diagram

If you need to add an options menu after swiping up, please add it in B. It’s B, B, B!

1
2
3
4
5
6
override var previewActionItems: [UIPreviewActionItem] {
  let profileAction = UIPreviewAction(title: "View Merchant Info", style: .default) { (action, viewController) -> Void in
    // Action after clicking
  }
  return [profileAction]
}

Returning an empty array indicates that this feature is not used.

Done!

2. APP Shortcut Launch

Step 1

Add the UIApplicationShortcutItems parameter in info.plist, type Array

And add menu items (Dictionary) within it, with the following Key-Value settings:

  • [Required] UIApplicationShortcutItemType: Identifier string, used for judgment in AppDelegate
  • [Required] UIApplicationShortcutItemTitle: Option title
  • UIApplicationShortcutItemSubtitle: Option subtitle

  • UIApplicationShortcutItemIconType: Use system icon

Referenced from [this article](https://qiita.com/kusumotoa/items/f33c89f150cd0937d003){:target="_blank"}

Referenced from this article

  • UIApplicationShortcutItemIconFile: Use custom icon (size: 35x35, single color), use either this or UIApplicationShortcutItemIconType
  • UIApplicationShortcutItemUserInfo: Additional information EX: [id:1]

My settings as shown above

My settings as shown above

Step 2

Add the handling function in AppDelegate

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
func application(_ application: UIApplication, performActionFor shortcutItem: UIApplicationShortcutItem, completionHandler: @escaping (Bool) -> Void) {
    var info = shortcutItem.userInfo
  
    switch shortcutItem.type {
    case "searchShop":
      //
    case "topicList":
      //
    case "likeWorksPic":
      //
    case "marrybarList":
      //
    default:
        break
    }
    completionHandler(true)
}

Done!

Conclusion

Adding 3D Touch functionality to the APP is not difficult and users will find it very considerate ❤; it can be combined with design operations to enhance user experience. However, currently, only the two functions mentioned above can be implemented, and since iPhone 6s and below/iPad/iPhone XR do not support 3D Touch, the actual functionalities that can be done are even fewer, mainly serving as an aid to enhance the experience.

p.s.

If you test carefully enough, you will notice the above effect. When part of the image in the CollectionView has already slid out of the screen, pressing it will result in the above situation 😅

If you test carefully enough, you will notice the above effect. When part of the image in the CollectionView has already slid out of the screen, pressing it will result in the above situation 😅

If you have any questions or feedback, feel free to contact me.

===

本文中文版本

===

This article was first published in Traditional Chinese on Medium ➡️ View Here


This post is licensed under CC BY 4.0 by the author.

Exploring iOS 12 CoreML — Automatically Predict Article Categories Using Machine Learning, Even Train the Model Yourself!

All About iOS UUID (Swift/iOS ≥ 6)