Post

iOS APP 3D Touch 功能实作|Swift 教学与预览、捷径启动技巧

针对iOS APP开发者,解析如何用Swift实作3D Touch预览与捷径启动功能,解决使用者操作不便问题,提升APP互动体验并增加使用黏著度。

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.