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

参考如下:

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

<key>UIApplicationShortcutItems</key>
    <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的设备上。

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

IconNameMeaningObjective-CSwift
Add quick action iconAddCreates a new item.UIApplicationShortcutIconTypeAddadd
Alarm quick action iconAlarmSets or displays an alarm.UIApplicationShortcutIconTypeAlarmalarm
Audio quick action iconAudioDenotes or adjusts audio.UIApplicationShortcutIconTypeAudioaudio
Bookmark quick action iconBookmarkCreates a bookmark or shows bookmarks.UIApplicationShortcutIconTypeBookmarkbookmark
Capture Photo quick action iconCapture PhotoCaptures a photo.UIApplicationShortcutIconTypeCapturePhotocapturePhoto
Capture Video quick action iconCapture VideoCaptures a video.UIApplicationShortcutIconTypeCaptureVideocaptureVideo
Cloud quick action iconCloudDenotes, displays, or initiates a cloud-based service.UIApplicationShortcutIconTypeCloudcloud
Compose quick action iconComposeComposes new editable content.UIApplicationShortcutIconTypeComposecompose
Confirmation quick action iconConfirmationDenotes that an action is complete.UIApplicationShortcutIconTypeConfirmationconfirmation
Contact quick action iconContactChooses or displays a contact.UIApplicationShortcutIconTypeContactcontact
Date quick action iconDateDisplays a calendar or event, or performs a related action.UIApplicationShortcutIconTypeDatedate
Favorite quick action iconFavoriteDenotes or marks a favorite item.UIApplicationShortcutIconTypeFavoritefavorite
Home quick action iconHomeIndicates or displays a home screen. Indicates, displays, or routes to a physical home.UIApplicationShortcutIconTypeHomehome
Invitation quick action iconInvitationDenotes or displays an invitation.UIApplicationShortcutIconTypeInvitationinvitation
Location quick action iconLocationDenotes the concept of location or accesses the current geographic location.
UIApplicationShortcutIconTypeLocation
location
Love quick action iconLoveDenotes or marks an item as loved.UIApplicationShortcutIconTypeLovelove
Mail quick action iconMailCreates a Mail message.UIApplicationShortcutIconTypeMailmail
Mark Location quick action iconMark LocationDenotes, displays, or saves a geographic location.UIApplicationShortcutIconTypeMarkLocationmarkLocation
Message quick action iconMessageCreates a new message or denotes the use of messaging.UIApplicationShortcutIconTypeMessagemessage
Pause quick action iconPausePauses media playback. Always store the current location when pausing, so playback can resume later.UIApplicationShortcutIconTypePausepause
Play quick action iconPlayBegins or resumes media playback.UIApplicationShortcutIconTypePlayplay
Prohibit quick action iconProhibitDenotes that something is disallowed.UIApplicationShortcutIconTypeProhibitprohibit
Search quick action iconSearchEnters a search mode.
UIApplicationShortcutIconTypeSearch
search
Share quick action iconShareShares content with others or to social media.UIApplicationShortcutIconTypeShareshare
Shuffle quick action iconShuffleIndicates or initiates shuffle mode.UIApplicationShortcutIconTypeShuffleshuffle
Task quick action iconTaskDenotes an uncompleted task or marks a task as complete.UIApplicationShortcutIconTypeTasktask
Task Completed quick action iconTask CompletedDenotes a completed task or marks a task as not complete.UIApplicationShortcutIconTypeTaskCompletedtaskCompleted
Time quick action iconTimeDenotes or displays a clock or timer.UIApplicationShortcutIconTypeTimetime
Update quick action iconUpdateUpdates content.UIApplicationShortcutIconTypeUpdateupdate

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对象,如下图:

最终运行结果如下,动态创建的第三个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:)方法传递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界面,其经过如下图:

      

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

如要想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的博客,如需转载,请标明出处。

 

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值