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 捷径启动功能

  1. 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.