1. 概述
作为一个开发者,有一个学习的氛围跟一个交流圈子特别重要,这是一个我的iOS交流群:196800191,加群密码:112233,不管你是小白还是大牛欢迎入驻 ,分享BAT,阿里面试题、面试经验,讨论技术, 大家一起交流学习成长!
在支持3D Touch的设备上,用户可以通过对触摸屏施加不同程度的压力来访问其他功能,应用程序可以通过显示上下文菜单(或支持Peek和Pop)来响应,以显示一些可供用户操作的选项或者行为。
在运行iOS 13及以后版本的设备上,人们可以使用touch和hold手势来打开上下文菜单,而不管设备是否支持3D touch。在3D触摸设备上,手势可以更快地显示上下文菜单,对特性的独立访问。
3D Touch主要分为两种:
- 主屏幕快捷操作(Home Screen Quick Actions)
- 预览和跳转(Peek and Pop)
本文所有示例及代码全部基于xcode12,iOS13.
2. 主屏幕快捷操作(Home Screen Quick Actions)
当用户长按APP图标或者施加一定压力的时候,程序会在适当的位置展示出一个菜单选项列表。当用户选择一个快速动作时,APP启动,程序的应用委托对象接收到快速动作消息。
配置一个主屏幕快捷操作,可分为静态和动态两种方式。
2.1 静态添加快捷操作(Static quick actions)
这种方式主要是在项目的Info.plist文件中添加相关的属性。
参考如下:或者像下面这样配置,效果都一样:
<array>
<dict>
<key>UIApplicationShortcutItemIconFile</key>
<string>open-favorites</string>
<key>UIApplicationShortcutItemTitle</key>
<string>Favorites</string>
<key>UIApplicationShortcutItemType</key>
<string>com.mycompany.myapp.openfavorites</string>
<key>UIApplicationShortcutItemUserInfo</key>
<dict>
<key>key1</key>
<string>value1</string>
</dict>
</dict>
<dict>
<key>UIApplicationShortcutItemIconType</key>
<string>UIApplicationShortcutIconTypeCompose</string>
<key>UIApplicationShortcutItemTitle</key>
<string>New Message</string>
<key>UIApplicationShortcutItemType</key>
<string>com.mycompany.myapp.newmessage</string>
<key>UIApplicationShortcutItemUserInfo</key>
<dict>
<key>key2</key>
<string>value2</string>
</dict>
</dict>
</array>
下面针对上面配置的key值来了解一下:
Key | 配置要求 | 描述 |
---|---|---|
UIApplicationShortcutItemType | 必填 | 快捷操作项的唯一标识,用于区别其他快捷操作项。 |
UIApplicationShortcutItemTitle | 必填 | 快捷操作项的主标题.如果主标题能够一行显示的话,就一行显示。如果太长了一行显示不小的话,如果没有配置副标题,那么主标题显示两行。 |
UIApplicationShortcutItemSubtitle | 选填 | 快捷操作项的副标题,显示在主标题的下面。如果制定了副标题,但是主标题又太长了,那么主标题只显示一行,多余的打点。 |
UIApplicationShortcutItemIconType | 选填 | 配置系统提供的快捷操作项的图标。 |
UIApplicationShortcutItemIconFile | 选填 | 配置自定义的快捷操作项的图标,如果配置了这个key,那么系统将会忽略UIApplicationShortcutItemIconType自定义图标必须是方形的,单一颜色,尺寸为35x35 points。 |
UIApplicationShortcutItemUserInfo | 选填 | 快捷操作项的附加信息,字典类型。 |
注明:这些key用在iOS9及以上且支持3D Touch的设备上。
2.2 动态添加快捷操作(Dynamic quick actions)
这种方式主要通过代码的形式把UIApplicationShortcutItem对象数组传递给UIApplication单例对象。
UIApplicationShortcutItem就是屏幕上弹出的列表中列表项对应的数据模型,下面看一下这个类的初始化方法以及相关属性:
如果同时使用静态和动态的方法添加,其添加的先后顺序是:先添加静态UIApplicationShortcutItem对象,如果静态UIApplicationShortcutItem对象不足4个,则继续添加动态UIApplicationShortcutItem对象。官方文档提及到最多只能添加4个UIApplicationShortcutItem对象。
下面看一下示例代码:
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
// Override point for customization after application launch.
let dynamicIcon1 = UIApplicationShortcutIcon(systemImageName: "play")
let dynamicItem1 = UIApplicationShortcutItem(type: "play", localizedTitle: "播放", localizedSubtitle: "播放喜欢的内容", icon: dynamicIcon1, userInfo: nil)
let dynamicIcon2 = UIApplicationShortcutIcon(systemImageName: "message")
let dynamicItem2 = UIApplicationShortcutItem(type: "message", localizedTitle: "消息", localizedSubtitle: "发送消息", icon: dynamicIcon2, userInfo: nil)
let dynamicIcon3 = UIApplicationShortcutIcon(systemImageName: "favorite")
let dynamicItem3 = UIApplicationShortcutItem(type: "favorite", localizedTitle: "喜欢", localizedSubtitle: "喜欢的节目", icon: dynamicIcon3, userInfo: nil)
UIApplication.shared.shortcutItems = [dynamicItem1, dynamicItem2, dynamicItem3]
return true
}
上面代码动态添加了3个UIApplicationShortcutItem对象,另外还配置了两个静态UIApplicationShortcutItem对象,如下图:
最终运行结果如下,动态创建的第三个UIApplicationShortcutItem对象,没有显示出来。
2.3 响应方法
当点击对应的快捷操作项后,APP被唤醒或者启动.
1. 当APP没有运行起来的时候,点击后APP启动,并且通过scene(_:willConnectTo:options:)
方法中的connectionOptions参数携带shortcut对象信息。这个方法中先保存shortcut对象信息,带APP完全启动后,再根据shortcut对象信息执行后续操作。
func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) {
/** Process the quick action if the user selected one to launch the app.
Grab a reference to the shortcutItem to use in the scene.
*/
if let shortcutItem = connectionOptions.shortcutItem {
// Save it off for later when we become active.
savedShortCutItem = shortcutItem
}
}
2. 当APP已经运行起来(包括压在后台),点击后APP唤醒,并且调用 [windowScene(_:performActionFor:completionHandler:)](https://developer.apple.com/documentation/uikit/uiwindowscenedelegate/3238088-windowscene)方法传递
shortcut对象信息。
func windowScene(_ windowScene: UIWindowScene, performActionFor shortcutItem: UIApplicationShortcutItem, completionHandler: @escaping (Bool) -> Void) {
print(shortcutItem.localizedTitle)
}
3. 预览和跳转(Peek and Pop)
Peek和Pop是应用内的一种全新交互模式,当用户不断增加力量在控件上按压,会依次进入四个阶段:
- 轻按控件,除触发Peek的控件外,其他区域全部虚化 。
- 继续用力Peek被触发,展示Pop界面快照 。
- 向上滑动展示快捷选项 。
- 继续用力跳转进入Pop界面。
比如iPhone手机的信息APP以及微信,都有这个功能。
下面看一个Demo,Demo中会从一个tableview界面,按压cell调入到detail界面,其经过如下图:
简书88.png
上面四个图正好对应了四个阶段。
如要想cell用力按压后有预览效果,首先需要向cell注册3D功能,代码如下:
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "Cell")
cell?.textLabel?.text = "这是第\(indexPath.row)行"
// 判断是否支持3D Touch功能。
if traitCollection.forceTouchCapability == .available {
self.registerForPreviewing(with: self, sourceView: cell!)
}
return cell!
}
注册完之后,需要实现其协议方法:
@available(iOS 9.0, *)
public protocol UIViewControllerPreviewingDelegate : NSObjectProtocol {
// 该方法返回一个可供预览的视图,如果返回nil,则无预览图。
@available(iOS, introduced: 9.0, deprecated: 13.0, renamed: "UIContextMenuInteraction")
func previewingContext(_ previewingContext: UIViewControllerPreviewing, viewControllerForLocation location: CGPoint) -> UIViewController?
// 实现该方法,则会跳入到预览图控制器界面。
@available(iOS, introduced: 9.0, deprecated: 13.0, renamed: "UIContextMenuInteraction")
func previewingContext(_ previewingContext: UIViewControllerPreviewing, commit viewControllerToCommit: UIViewController)
}
Demo中两个协议方法现实如下:
func previewingContext(_ previewingContext: UIViewControllerPreviewing, viewControllerForLocation location: CGPoint) -> UIViewController? {
// 获取按压的cell
guard let cell = previewingContext.sourceView as? UITableViewCell else {
return nil
}
// 获取cell的indexPath
guard let indexPath = tableView.indexPath(for: cell) else {
return nil
}
// sourceRect边界外部虚化。
previewingContext.sourceRect = cell.frame
let detailVC = DetailViewController(nibName: "DetailViewController", bundle: nil)
detailVC.number = indexPath.row
detailVC.title = "\(indexPath.row)"
return detailVC
}
func previewingContext(_ previewingContext: UIViewControllerPreviewing, commit viewControllerToCommit: UIViewController) {
show(viewControllerToCommit, sender: self)
}
实现上述代码即可实现1、2、4个阶段的功能。
如果要实现预览界面上滑显示快捷项列表,则需要在目标控制器复写previewActionItems属性。
下面在目标控制器(DetailViewController)界面复写previewActionItems属性。
override var previewActionItems: [UIPreviewActionItem] {
let action1 = UIPreviewAction(title: "喜欢", style: .default) { (action, controller) in
}
let action2 = UIPreviewAction(title: "收藏", style: .default) { (action, controller) in
}
let action3 = UIPreviewAction(title: "删除", style: .default) { (action, controller) in
}
return [action1, action2, action3]
}
以上就完成了3D Touch功能,当然此功能不限于UITableView。在iOS13之后,上面的相关方法以及协议将会废弃,由UIContextMenuInteraction取代,关于UIContextMenuInteraction,在后续博文中将继续介绍,敬请关注!
参考文档:
本篇文章出自https://blog.csdn.net/guoyongming925的博客,如需转载,请标明出处。
原文作者:Daniel_Coder
原文地址:https://www.jianshu.com/writer#/notebooks/48715467/notes/81067285/preview
网友评论