iOS-3DTouch学习一:添加主屏快速操作(Add Home Screen Quick Actions)

1 概述

3D Touch,是在iOS9.0之后推出的一项快速访问应用功能的一项技术。在支持3D Touch的设备(iPhone 6s及以后的机型)上,用户使用比触摸和保持所需的更多压力按下应用程序的图标,以唤起主屏幕快速操作,从而可以使用主屏幕快速操作来访问应用中常用的功能。
注意:如果应用程序未做任何3D Touch 快速操作项目,上架到App Store后貌似会自动添加一个分享的操作。
官方开发文档

2 应用场景

我们使用3D Touch主要有两个应用场景:

  1. 在屏幕快速访问App内某些功能,如扫码、拍照等功能。本篇主要讲述在主屏幕上添加3D Touch操作的实现。简易OC版本Demo地址官方swift版本地址
  2. 在应用内实现实现一些功能,如预览等功能。传送门

3 定义主屏幕3D Touch操作

3D Touch快速操作,可以使用两种定义方式:

  • 在构建时静态定义(Define Static Quick Actions)
  • 在运行时动态定义(Define Dynamic Quick Actions)
3.1 构建时静态定义(Define Static Quick Actions)

如果3D Touch操作对于你的应用是不变的,那么你可以定义为静态快速操作,具体步骤就是在info.plist文件中添加keyUIApplicationShortcutItems,类型为Array。每个item都是一个UIApplicationShortcutItem

UIApplicationShortcutItems 官方说法翻译:
UIApplicationShortcutItems(Array - iOS)指定应用程序的静态主屏幕快速操作。该键包含一系列字典。每个字典都包含有关单个快速操作及其使用方式的详细信息。
我们可以将应用程序的静态快速操作指定为字典数组。当用户在支持3D Touch的设备上按主屏幕图标时,主屏幕上显示的应用程序快速操作数量由系统决定。
我们在Info.plist文件中定义的静态快速操作将显示在主屏幕上,其顺序与文件中显示的顺序相同。系统首先使用静态快速操作填充主屏幕快速操作集,并且仅当有可用的其他插槽时,它还会显示已定义的动态快速操作。

以下代码和屏幕截图显示了Xcode属性列表编辑器中两个静态快速操作的示例定义:

<key>UIApplicationShortcutItems</key>
<array>
    <dict>
        <key>UIApplicationShortcutItemType</key>
        <string>SearchAction</string>
        <key>UIApplicationShortcutItemIconType</key>
        <string>UIApplicationShortcutIconTypeSearch</string>
        <key>UIApplicationShortcutItemTitle</key>
        <string>Search</string>
        <key>UIApplicationShortcutItemSubtitle</key>
        <string>Search for an item</string>
        <key>UIApplicationShortcutItemUserInfo</key>
            <dict>
              <key>key1</key>
              <string>value1</string>
             </dict>
    </dict>
    <dict>
        <key>UIApplicationShortcutItemType</key>
        <string>ShareAction</string>
        <key>UIApplicationShortcutItemIconType</key>
        <string>UIApplicationShortcutIconTypeShare</string>
        <key>UIApplicationShortcutItemTitle</key>
        <string>Share</string>
        <key>UIApplicationShortcutItemSubtitle</key>
        <string>Share an item</string>
        <key>UIApplicationShortcutItemUserInfo</key>
            <dict>
              <key>key2</key>
              <string>value2</string>
        </dict>
    </dict>
</array>
image.png.png

其中各个关键字释义如下:
UIApplicationShortcutItemType: 快捷可选项的标志类型的字符串(必填)
UIApplicationShortcutItemTitle: 快捷可选项的标题(必填)
UIApplicationShortcutItemSubtitle: 快捷可选项的子标题(可选)
UIApplicationShortcutItemIconType: 快捷可选项的图标(可选)
UIApplicationShortcutItemIconFile: 快捷可选项的自定义图标(可选)
UIApplicationShortcutItemUserInfo: 快捷可选项的附加信息,比如通过点击某个快速操作,进行传值(可选)

注意:UIApplicationShortcutItemType键对应的类型值会在用户点击了其中一个ShortcutItem时返回,也就是我们可以使用这个字符串来确定当前用户点击的是什么类型的ShortcutItem,而UIApplicationShortcutItemUserInfo我们可以获取点击快速操作传递过来的值。

3.2 运行时动态定义(Define Static Quick Actions)

iOS9.0之后,UIApplication添加了一个分类,分类中有一个属性shortcutItems,我们可以通过设置这个属性,对3D Touch所对应的操作进行配置。具体的时机,可以是程序由前台退到后台时,也可以在程序启动时,自己把握。可操作个数无需控制,系统会自己处理显示的数据,不过我们也不应该添加的太多,毕竟多了不显示也是没用。

  @class UIApplicationShortcutItem;
  @interface UIApplication (UIShortcutItems)
  // Register shortcuts to display on the home screen, or retrieve currently registered shortcuts.
  @property (nullable, nonatomic, copy) NSArray<UIApplicationShortcutItem   *> *shortcutItems NS_AVAILABLE_IOS(9_0) __TVOS_PROHIBITED;
@end

说到动态添加,就不得不说一下UIApplicationShortcutItem这个类了,这个类为我们提供了代码创建的方式,我们看一下这个类的官方定义:

NS_CLASS_AVAILABLE_IOS(9_0) __TVOS_PROHIBITED
@interface UIApplicationShortcutItem : NSObject <NSCopying, NSMutableCopying>

- (instancetype)init NS_UNAVAILABLE;
- (instancetype)initWithType:(NSString *)type localizedTitle:(NSString *)localizedTitle localizedSubtitle:(nullable NSString *)localizedSubtitle icon:(nullable UIApplicationShortcutIcon *)icon userInfo:(nullable NSDictionary *)userInfo NS_DESIGNATED_INITIALIZER;
- (instancetype)initWithType:(NSString *)type localizedTitle:(NSString *)localizedTitle;

// An application-specific string that identifies the type of action to perform.
@property (nonatomic, copy, readonly) NSString *type;

// Properties controlling how the item should be displayed on the home screen.
@property (nonatomic, copy, readonly) NSString *localizedTitle;
@property (nullable, nonatomic, copy, readonly) NSString *localizedSubtitle;
@property (nullable, nonatomic, copy, readonly) UIApplicationShortcutIcon *icon;

// Application-specific information needed to perform the action.
// Will throw an exception if the NSDictionary is not plist-encodable.
@property (nullable, nonatomic, copy, readonly) NSDictionary<NSString *, id <NSSecureCoding>> *userInfo;

@end

其中对于实例方法initWithType:localizedTitle:localizedSubtitle:icon:userInfo:各个参数释义如下:
type: 快捷可选项的标志类型的字符串(必填)
localizedTitle: 快捷可选项的标题(必填)
localizedSubtitle: 快捷可选项的子标题(可选)
icon: 快捷可选项的图标(可选)
userInfo: 快捷可选项的附加信息,比如通过点击某个快速操作,进行传值(可选)

注意:经过测试,如果同时使用静态方式和动态方式两种定义方式,则最终会合并,并且静态方式定义的快速操作靠近程序图标。

3.3 点击快速操作时的数据传递

至此,我们学习了定义3D Touch中的快速操作,下面我们说一下当我们进行3D Touch操作时的数据传递。我们需要依赖初始化UIApplicationShortcutItem实例对象时,传入的userInfo字典。
通过UIApplicationShortcutItem类中的定义,我们可以看到,该类有个userInfo的属性,该属性中存放值要全部遵循<NSSecureCoding>协议,幸运的是字符串是遵循该协议的。

注意:通过静态方式定义的快速操作,可以通过将其包含在应用程序的Info.plist文件中的UIApplicationShortcutItemUserInfo键中来传递userInfo数据。

下面我们举个栗子,添加一个分享操作:

UIApplicationShortcutItem *shareItem = [[UIApplicationShortcutItem alloc] initWithType:@"com.yuyangkk.share" localizedTitle:@"分享" localizedSubtitle:@"分享副标题" icon:[UIApplicationShortcutIcon iconWithType:UIApplicationShortcutIconTypeShare] userInfo:@{@"Name":@"Hello world"}];
[UIApplication sharedApplication].shortcutItems = @[shareItem];

运行App,得到的效果是:


Simulator Screen Shot - iPhone X - 2018-09-13 at 22.21.18.png
3.4 响应快速操作事件

当用户触发主屏幕快速操作时,应用会通过以下两种方式之一得到通知:

  • 如果应用尚未加载(启动),则会启动它,并通过应用程序application: didFinishLaunchingWithOptions:方法中的launchOptions参数传递快捷项的详细信息。
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
    // Override point for customization after application launch.
    
    // 如果launchOptions包含相应的启动选项键,则主屏幕快速操作负责启动应用程序。 应用完成初始化后,我们可以存储快速操作以进行处理。
    if (launchOptions[UIApplicationLaunchOptionsShortcutItemKey]) {
        // do something
        UIApplicationShortcutItem *item = launchOptions[UIApplicationLaunchOptionsShortcutItemKey];
        UIAlertController *alert = [UIAlertController alertControllerWithTitle:item.localizedTitle message:[NSString stringWithFormat:@"传递过来的值是:%@",item.userInfo] preferredStyle:UIAlertControllerStyleAlert];
        UIAlertAction *action = [UIAlertAction actionWithTitle:@"取消" style:UIAlertActionStyleCancel handler:nil];
        [alert addAction:action];
        [application.keyWindow.rootViewController presentViewController:alert animated:YES completion:nil];
    }
    return YES;
}
  • 如果您的应用程序已加载(启动),系统将调用应用程序的委托方法application: performActionForShortcutItem: completionHandler中的shortcutItem进行传值。
- (void)application:(UIApplication *)application performActionForShortcutItem:(UIApplicationShortcutItem *)shortcutItem completionHandler:(void (^)(BOOL))completionHandler{
    // 程序已经加载到内存中,点击3D Touch中的一个快速操作,会调用该代理方法,我们也可以存储快速操作,以便处理
    // do something
    UIAlertController *alert = [UIAlertController alertControllerWithTitle:shortcutItem.localizedTitle message:[NSString stringWithFormat:@"传递过来的值是:%@",shortcutItem.userInfo] preferredStyle:UIAlertControllerStyleAlert];
    UIAlertAction *action = [UIAlertAction actionWithTitle:@"取消" style:UIAlertActionStyleCancel handler:nil];
    [alert addAction:action];
    [application.keyWindow.rootViewController presentViewController:alert animated:YES completion:nil];
}

简单的使用,到此就结束了,深入的还需要各位小伙伴去挖掘,如果觉得对你有帮助,不要吝啬你的小💗💗哦。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 160,108评论 4 364
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,699评论 1 296
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 109,812评论 0 244
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 44,236评论 0 213
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,583评论 3 288
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,739评论 1 222
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,957评论 2 315
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,704评论 0 204
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,447评论 1 246
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,643评论 2 249
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,133评论 1 261
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,486评论 3 256
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,151评论 3 238
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,108评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,889评论 0 197
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,782评论 2 277
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,681评论 2 272