Post

提升使用者體驗,現在就為您的 iOS APP 加上 3D TOUCH 功能(Swift)

iOS 3D TOUCH 應用

提升使用者體驗,現在就為您的 iOS APP 加上 3D TOUCH 功能(Swift)

Click here to view the English version of this article.

点击这里查看本文章简体中文版本。

基於 SEO 考量,本文標題與描述經 AI 調整,原始版本請參考內文。

文章目錄


[Deprecated]提升使用者體驗,現在就為您的 iOS APP 加上 3D TOUCH 功能(Swift)

iOS 3D TOUCH 應用

[Deprecated] 2020/06/14

iPhone 11 以上版本已取消 3D Touch 功能;改用 Haptic Touch 取代,實作方式也有所不同。

前陣子在專案開發閒暇之時,探索了許多 iOS 的有趣功能: CoreMLVisionNotification Service Extension 、Notification Content Extension、Today Extension、Core Spotlight、Share Extension、SiriKit (部分已整理成文章、其他項目敬請期待🤣)

其中還有今日的主角: 3D Touch功能

這個早在 iOS 9/iPhone 7之後 就開始支援的功能,直到我自己從iPhone 6換到iPhone 8 後才體會到它的好用之處!

3D Touch能在APP中實做兩個項目,如下:

1. Preview ViewController 預覽功能 — [結婚吧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 預覽功能 — 結婚吧APP

2. 3D Touch Shortcut APP 捷徑啟動功能

2. 3D Touch Shortcut APP 捷徑啟動功能

其中第一項是應用最廣且效果最好的 (Facebook:動態消息內容預覽、Line:偷看訊息),第二項 APP 捷徑啟動 目前看數據是鮮少人使用所以放最後在講。

1. Preview ViewController 預覽功能:

功能展示如上圖1所示,ViewController 預覽功能支援

  • 3D Touch重壓時背景虛化
  • 3D Touch重壓住時跳出ViewController預覽視窗
  • 3D Touch重壓住時跳出ViewController預覽視窗,往上滑可在下方加入選項選單
  • 3D Touch重壓放開返回視窗
  • 3D Touch重壓後再用力進入目標ViewController

這裡將分 A:列表視窗B:目標視窗 個別列出要實作的程式碼:

由於在 B中 沒有方式能判斷當前是預覽還是真的進入此視窗,所以我們先建立一個Protocol傳遞值,用來判斷

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

這樣我們就能在 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 {
       //若為預覽視窗時...例如:變全螢幕、隱藏工具列
     } else {
       //完整模式時照正常顯示
   } 
}

A:列表視窗,可以是 UITableView 或 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 {
    //註冊能3D Touch 的 View
    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 {
    //3D Touch放開後,要做的處理
    func previewingContext(_ previewingContext: UIViewControllerPreviewing, commit viewControllerToCommit: UIViewController) {
        
        //現在要直接跳轉的該頁面了,所以將ViewController的預覽模式參數取消:
        if var viewControllerToCommit = viewControllerToCommit as? UIViewControllerPreviewable {
            viewControllerToCommit.is3DTouchPreview = false
        }
        self.navigationController?.pushViewController(viewControllerToCommit, animated: true)
    }
    
    //控制3D Touch的Cell位置,欲顯示的ViewController
    func previewingContext(_ previewingContext: UIViewControllerPreviewing, viewControllerForLocation location: CGPoint) -> UIViewController? {
        
        //取得當前點的indexPath/cell實體
        //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 }
      
        //欲顯示的ViewController
        let targetViewController = UIStoryboard(name: "StoryboardName", bundle: nil).instantiateViewController(withIdentifier: "ViewControllerIdentifier")
        
        //背景虛化時保留區域(一般為點擊位置),附圖1
        previewingContext.sourceRect = cell.frame
        
        //3D Touch視窗大小,預設為自適應,不需更改
        //要修改請用:targetViewController.preferredContentSize = CGSize(width: 0.0, height: 0.0)
        
        //告知預覽的ViewController目前為預覽模式:
        if var targetViewController = targetViewController as? UIViewControllerPreviewable {
            targetViewController.is3DTouchPreview = true
        }
        
        //回傳nil則無任何作用
        return nil
    }
}

請注意!其中的註冊能3D Touch 的 View 這塊要放在 traitCollectionDidChange 之中而非 “viewDidLoad” ( 請參考此篇內容 )

關於要加放在哪裡這塊我踩了許多雷,網路有些資料寫viewDidLoad、有的寫在cellforItem中,但這兩個地方都會出現偶爾失效或部分cell失效的問題。

附圖1 背景虛化保留區示意圖

附圖1 背景虛化保留區示意圖

如果您需要上滑後在下方加入選項選單請在 B 之中加入,是B 是B 是B哦!

1
2
3
4
5
6
override var previewActionItems: [UIPreviewActionItem] {
  let profileAction = UIPreviewAction(title: "查看商家資訊", style: .default) { (action, viewController) -> Void in
    //點擊後的操作
  }
  return [profileAction]
}

回傳空陣列表示不使用此功能。

完成!

2. APP 捷徑啟動

第一步

在 info.plist 中加入 UIApplicationShortcutItems 參數,類型 Array

並在其中新增選單項目(Dictionary),其中Key-Value的設定對應如下:

  • [必填] UIApplicationShortcutItemType : 識別字串,在AppDelegate中做判斷使用
  • [必填] UIApplicationShortcutItemTitle : 選項標題
  • UIApplicationShortcutItemSubtitle : 選項子標題

  • UIApplicationShortcutItemIconType : 使用系統圖標

參考自 [此篇文章](https://qiita.com/kusumotoa/items/f33c89f150cd0937d003){:target="_blank"}

參考自 此篇文章

  • UIApplicationShortcutItemIconFile : 使用自定義圖標(size:35x35,單色),與UIApplicationShortcutItemIconType擇ㄧ使用
  • UIApplicationShortcutItemUserInfo : 更多附加資訊EX: [id:1]

我的設定如上圖

我的設定如上圖

第二步

在AppDelegate中新增處理的 Function

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)
}

完成!

結語

在APP中加入 3D Touch的功能並不難,對使用者來說也會覺得很貼心❤;可以搭配設計操作增加使用者體驗;但目前就只有上述兩個功能可做在加上iPhone 6s以下/iPad/iPhone XR都不支援3D Touch所以實際能做的功能又更少了,只能以輔助、增加體驗為主。

p.s.

如果你測的夠細會發現以上效果,在CollectionView滑動中圖有部分已經滑出畫面這時按壓就會出現以上情況😅

如果你測的夠細會發現以上效果,在CollectionView滑動中圖有部分已經滑出畫面這時按壓就會出現以上情況😅

有任何問題及指教歡迎 與我聯絡


Buy me a beer

本文首次發表於 Medium (點此查看原始版本),由 ZMediumToMarkdown 提供自動轉換與同步技術。

Improve this page on Github.

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