iOS开发之3D Touch(快速添加3D Touch功能)

1. 概述

在支持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文件中添加相关的属性。

参考如下:

iOS开发之3D Touch(快速添加3D Touch功能)_第1张图片

或者像下面这样配置,效果都一样:

UIApplicationShortcutItems
    
        
            UIApplicationShortcutItemIconFile
            open-favorites
            UIApplicationShortcutItemTitle
            Favorites
            UIApplicationShortcutItemType
            com.mycompany.myapp.openfavorites
            UIApplicationShortcutItemUserInfo
            
                key1
                value1
            
        
        
            UIApplicationShortcutItemIconType
            UIApplicationShortcutIconTypeCompose
            UIApplicationShortcutItemTitle
            New Message
            UIApplicationShortcutItemType
            com.mycompany.myapp.newmessage
            UIApplicationShortcutItemUserInfo
            
                key2
                value2
            
        
    

下面针对上面配置的key值来了解一下:

Key

配置要求

描述

UIApplicationShortcutItemType  

必填

快捷操作项的唯一标识,用于区别其他快捷操作项。

UIApplicationShortcutItemTitle

必填

快捷操作项的主标题。

如果主标题能够一行显示的话,就一行显示。如果太长了一行显示不小的话,如果没有配置副标题,那么主标题显示两行。

UIApplicationShortcutItemSubtitle

选填

快捷操作项的副标题,显示在主标题的下面。

如果制定了副标题,但是主标题又太长了,那么主标题只显示一行,多余的打点。

UIApplicationShortcutItemIconType

选填

配置系统提供的快捷操作项的图标。

UIApplicationShortcutItemIconFile

选填

配置自定义的快捷操作项的图标,如果配置了这个key,那么系统将会忽略UIApplicationShortcutItemIconType

自定义图标必须是方形的,单一颜色,尺寸为35x35 points。

UIApplicationShortcutItemUserInfo

选填 快捷操作项的附加信息,字典类型。

注明:这些key用在iOS9及以上且支持3D Touch的设备上。

下表为系统提供的快捷操作项的图标:

Icon Name Meaning Objective-C Swift
Add quick action icon Add Creates a new item. UIApplicationShortcutIconTypeAdd add
Alarm quick action icon Alarm Sets or displays an alarm. UIApplicationShortcutIconTypeAlarm alarm
Audio quick action icon Audio Denotes or adjusts audio. UIApplicationShortcutIconTypeAudio audio
Bookmark quick action icon Bookmark Creates a bookmark or shows bookmarks. UIApplicationShortcutIconTypeBookmark bookmark
Capture Photo quick action icon Capture Photo Captures a photo. UIApplicationShortcutIconTypeCapturePhoto capturePhoto
Capture Video quick action icon Capture Video Captures a video. UIApplicationShortcutIconTypeCaptureVideo captureVideo
Cloud quick action icon Cloud Denotes, displays, or initiates a cloud-based service. UIApplicationShortcutIconTypeCloud cloud
Compose quick action icon Compose Composes new editable content. UIApplicationShortcutIconTypeCompose compose
Confirmation quick action icon Confirmation Denotes that an action is complete. UIApplicationShortcutIconTypeConfirmation confirmation
Contact quick action icon Contact Chooses or displays a contact. UIApplicationShortcutIconTypeContact contact
Date quick action icon Date Displays a calendar or event, or performs a related action. UIApplicationShortcutIconTypeDate date
Favorite quick action icon Favorite Denotes or marks a favorite item. UIApplicationShortcutIconTypeFavorite favorite
Home quick action icon Home Indicates or displays a home screen. Indicates, displays, or routes to a physical home. UIApplicationShortcutIconTypeHome home
Invitation quick action icon Invitation Denotes or displays an invitation. UIApplicationShortcutIconTypeInvitation invitation
Location quick action icon Location Denotes the concept of location or accesses the current geographic location.
UIApplicationShortcutIconTypeLocation
location
Love quick action icon Love Denotes or marks an item as loved. UIApplicationShortcutIconTypeLove love
Mail quick action icon Mail Creates a Mail message. UIApplicationShortcutIconTypeMail mail
Mark Location quick action icon Mark Location Denotes, displays, or saves a geographic location. UIApplicationShortcutIconTypeMarkLocation markLocation
Message quick action icon Message Creates a new message or denotes the use of messaging. UIApplicationShortcutIconTypeMessage message
Pause quick action icon Pause Pauses media playback. Always store the current location when pausing, so playback can resume later. UIApplicationShortcutIconTypePause pause
Play quick action icon Play Begins or resumes media playback. UIApplicationShortcutIconTypePlay play
Prohibit quick action icon Prohibit Denotes that something is disallowed. UIApplicationShortcutIconTypeProhibit prohibit
Search quick action icon Search Enters a search mode.
UIApplicationShortcutIconTypeSearch
search
Share quick action icon Share Shares content with others or to social media. UIApplicationShortcutIconTypeShare share
Shuffle quick action icon Shuffle Indicates or initiates shuffle mode. UIApplicationShortcutIconTypeShuffle shuffle
Task quick action icon Task Denotes an uncompleted task or marks a task as complete. UIApplicationShortcutIconTypeTask task
Task Completed quick action icon Task Completed Denotes a completed task or marks a task as not complete. UIApplicationShortcutIconTypeTaskCompleted taskCompleted
Time quick action icon Time Denotes or displays a clock or timer. UIApplicationShortcutIconTypeTime time
Update quick action icon Update Updates content. UIApplicationShortcutIconTypeUpdate update

2.2 动态添加快捷操作(Dynamic quick actions)

这种方式主要通过代码的形式把UIApplicationShortcutItem对象数组传递给UIApplication单例对象。

UIApplicationShortcutItem就是屏幕上弹出的列表中列表项对应的数据模型,下面看一下这个类的初始化方法以及相关属性:

方法或属性 描述
init(type: String, localizedTitle: String) 初始化方法
init(type: String, localizedTitle: String, localizedSubtitle: String?, icon: UIApplicationShortcutIcon?, userInfo: [String : NSSecureCoding]?) 初始化方法
var localizedTitle: String 主标题
var localizedSubtitle: String? 副标题
var type: String 唯一标识
var icon: UIApplicationShortcutIcon? 图标
var userInfo: [String : NSSecureCoding]? 附加信息

如果同时使用静态和动态的方法添加,其添加的先后顺序是:先添加静态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对象,如下图:

iOS开发之3D Touch(快速添加3D Touch功能)_第2张图片

最终运行结果如下,动态创建的第三个UIApplicationShortcutItem对象,没有显示出来。

iOS开发之3D Touch(快速添加3D Touch功能)_第3张图片

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:)方法传递shortcut对象信息。

func windowScene(_ windowScene: UIWindowScene, performActionFor shortcutItem: UIApplicationShortcutItem, completionHandler: @escaping (Bool) -> Void) {
        print(shortcutItem.localizedTitle)
}

3. 预览和跳转(Peek and Pop)

Peek和Pop是应用内的一种全新交互模式,当用户不断增加力量在控件上按压,会依次进入四个阶段:

  1. 轻按控件,除触发Peek的控件外,其他区域全部虚化 。
  2. 继续用力Peek被触发,展示Pop界面快照 。
  3. 向上滑动展示快捷选项 。
  4. 继续用力跳转进入Pop界面。

比如iPhone手机的信息APP以及微信,都有这个功能。

下面看一个Demo,Demo中会从一个tableview界面,按压cell调入到detail界面,其经过如下图:

iOS开发之3D Touch(快速添加3D Touch功能)_第4张图片  iOS开发之3D Touch(快速添加3D Touch功能)_第5张图片  iOS开发之3D Touch(快速添加3D Touch功能)_第6张图片  iOS开发之3D Touch(快速添加3D Touch功能)_第7张图片

上面四个图正好对应了四个阶段。

如要想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://developer.apple.com/library/archive/documentation/UserExperience/Conceptual/Adopting3DTouchOniPhone/index.html#//apple_ref/doc/uid/TP40016543-CH1-SW1

本篇文章出自https://blog.csdn.net/guoyongming925的博客,如需转载,请标明出处。

 

你可能感兴趣的:(iOS开发,ios)