iOS APP 3D Touch 功能实作|Swift 教学与预览、捷径启动技巧
针对iOS APP开发者,解析如何用Swift实作3D Touch预览与捷径启动功能,解决使用者操作不便问题,提升APP互动体验并增加使用黏著度。
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 的有趣功能: CoreML 、 Vision 、 Notification 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中实做两个项目,如下:
- Preview ViewController 预览功能 — 结婚吧APP
- 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 背景虚化保留区示意图
如果您需要上滑后在下方加入选项选单请在 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 : 使用系统图标
参考自 此篇文章
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滑动中图有部分已经滑出画面这时按压就会出现以上情况😅
有任何问题及指教欢迎 与我联络 。
本文首次发表于 Medium (点击查看原始版本),由 ZMediumToMarkdown 提供自动转换与同步技术。