iOS开发3DTouch(一)

来源:互联网 发布:linux修改脚本 编辑:程序博客网 时间:2024/04/27 16:19

一、3D Touch 的简单介绍

①主屏幕的快捷操作:

在主屏幕按压app图标,有两种类型:静态操作(在info.plist中添加UIApplicationShortcutItems数组)和动态操作(利用 UIApplicationShortcutItem类和可用的api 创建新的对象,并将对象添加到shared UIApplication 的新属性 shortcutItems中去)。这两种操作,最多展示两行文字,和一个可以没有的图片。
这里写图片描述

②Peek And Pop

在iOS9之后,开发者可以使每一个UIViewController 类型的对象(包括子类)响应用户的压力操作,随着持续的压力操作,每一次都会经历3个过程:
1、预览内容(preview)是否可得到的
2、展示预览内容(preview),这也就是Peek; 同时也可以展示可以选择的事件 也就是peek quick actions
3、将preview正常展示 — 也就是pop
这里写图片描述

③Force Properties (压力属性)

在iOS9中,有两个新的属性来支持在app中实现3D Touch:force和maximumPossibleForce这些属性是你能够察觉到用户给予的压力在你APP接收的UIEvent对象中。

二、3D Touch 的使用

①检查3D Touch 是否可用(在controller中可以用如下方法检查)

if (self.traitCollection.forceTouchCapability == UIForceTouchCapabilityAvailable) {    NSLog(@"支持3d-touch");}//枚举如下typedef NS_ENUM(NSInteger, UIForceTouchCapability) {UIForceTouchCapabilityUnknown = 0,UIForceTouchCapabilityUnavailable = 1,UIForceTouchCapabilityAvailable = 2};

②主屏幕快捷操作

1、静态,在info.plist中添加 UIApplicationShortcutItems数组

最多可以展示四个元素,每个元素都是一个字典,其中包含的见键值对有:

UIApplicationShortcutItemType(必要键值对)字符串类型

在用户点击主屏幕出现的快捷操作之后,在appdelegate的委托方法中,可以使用该名称来判断是哪一个快捷操作被触发了,从而进行相关的操作。

UIApplicationShortcutItemTitle (必要键值对) 字符串类型

quick action 的名称,如果名字长度过长,而且没有指定subtitle 那么会显示两行,如果指定的suntitle那么将以省略号表示。

UIApplicationShortcutItemSubtitle  字符串类型

quick action 的子标题,通常用于描述该快捷操作,单行显示,多余的以省略号表示。

UIApplicationShortcutItemIconType  字符串类型

该快操作的图标(从系统所提供的图标选取);详细可以见UIApplicationShortcutIcon类中的UIApplicationShortcutIconType枚举,枚举如下:

typedef enum UIApplicationShortcutIconType : NSInteger {UIApplicationShortcutIconTypeCompose,UIApplicationShortcutIconTypePlay,UIApplicationShortcutIconTypePause,UIApplicationShortcutIconTypeAdd,UIApplicationShortcutIconTypeLocation,UIApplicationShortcutIconTypeSearch,UIApplicationShortcutIconTypeShare,UIApplicationShortcutIconTypeProhibit,UIApplicationShortcutIconTypeContact,UIApplicationShortcutIconTypeHome,UIApplicationShortcutIconTypeMarkLocation,UIApplicationShortcutIconTypeFavorite,UIApplicationShortcutIconTypeLove,UIApplicationShortcutIconTypeCloud,UIApplicationShortcutIconTypeInvitation,UIApplicationShortcutIconTypeConfirmation,UIApplicationShortcutIconTypeMail,UIApplicationShortcutIconTypeMessage,UIApplicationShortcutIconTypeDate,UIApplicationShortcutIconTypeTime,UIApplicationShortcutIconTypeCapturePhoto,UIApplicationShortcutIconTypeCaptureVideo,UIApplicationShortcutIconTypeTask,UIApplicationShortcutIconTypeTaskCompleted,UIApplicationShortcutIconTypeAlarm,UIApplicationShortcutIconTypeBookmark,UIApplicationShortcutIconTypeShuffle,UIApplicationShortcutIconTypeAudio,UIApplicationShortcutIconTypeUpdate}UIApplicationShortcutIconType;

以上为UIApplicationShortcutIconType枚举

UIApplicationShortcutItemIconFile  字符串

icon图片的路径,用户可以使用该键值对来使用自定义的图片;icon应当是正方形、单色,大小为35×35points
如果在工程中拖入一个图片,那么它的路径不需要前面的bundle路径。在用户自定义图像和系统图像都存在时,会展示用户自定的图像。

UIApplicationShortcutItemUserInfo  字典

用户信息;An optional, app-defined dictionary. One use for this dictionary is to provide app version information, as described in the “App Launch and App Update Considerations for Quick Actions” section of the overview in UIApplicationShortcutItem Class Reference.

2、动态

①添加
在app运行之后添加,添加方式如下(可以在一个你想添加的时机添加,比如一个ViewController的某个方法)

 //创建图标,可以不要UIApplicationShortcutIcon *icon1 = [UIApplicationShortcutIcon iconWithType:UIApplicationShortcutIconTypeFavorite]; //系统图标//创建itemUIApplicationShortcutItem *item1 = [[UIApplicationShortcutItem alloc] initWithType:@"love" localizedTitle:@"我喜欢" localizedSubtitle:nil icon:icon1 userInfo:nil];UIApplicationShortcutIcon *icon2 = [UIApplicationShortcutIcon iconWithTemplateImageName:@"itemIcon.jpg"]; //自定义图标UIApplicationShortcutItem *item2 = [[UIApplicationShortcutItem alloc] initWithType:@"gohome" localizedTitle:@"回家" localizedSubtitle:nil icon:icon2 userInfo:nil];//动态添加[UIApplication sharedApplication].shortcutItems = @[item1,item2];

②修改
要修改当前app的shortcutItem 就要先获得当前的shortcutItems
通过方法

NSArray *shortcutItemsArray = [UIApplication sharedApplication].shortcutItems;

便可以获得。但是这里需要注意一点,该方法获取不到静态的shortcutItem。
接下来是更改

 //创建一个可以更改的数组NSMutableArray *shortcutItemsArray = [[UIApplication sharedApplication].shortcutItems mutableCopy];//创建新的itemUIApplicationShortcutItem *item = [[UIApplicationShortcutItem alloc] initWithType:@"哈哈哈" localizedTitle:@"a"];[shortcutItemsArray replaceObjectAtIndex:0 withObject:item];//重新赋值给UIApplication[UIApplication sharedApplication].shortcutItems = shortcutItemsArray;

可以看到更改后的效果如下;
这里写图片描述
如果只是想更改某一个shortcutItem的某个属性,那么就取出该item进行mutableCopy然后更改再进行赋值(更改后替换可修改数组中的对应元素,然后再将数组赋给[UIApplication sharedApplication].shortcutItems)。修改方式如下:

 UIMutableApplicationShortcutItem *muItem = [[shortcutItemsArray objectAtIndex:0] mutableCopy];[muItem setLocalizedTitle:@"哈哈哈"];

如图所示,最底下的一行是添加的静态快捷方式,通过[UIApplication sharedApplication].shortcutItems方法的获取的数组,只能获取到“a”和“回家”这两个动态快捷方式,他们在数组中的顺序分别是从下到上,也就是说是“a”是第一个元素。

3、从主屏幕的快捷操作启动app

触发主屏幕的shortcutItem后会执行appDelegate中的

- (void)application:(UIApplication *)application performActionForShortcutItem:(UIApplicationShortcutItem *)shortcutItem completionHandler:(void (^)(BOOL))completionHandler;

方法,但是如果以下两个方法其中的任意一个返回了NO 该委托方法将不会被执行

- (BOOL)application:(UIApplication *)application willFinishLaunchingWithOptions:(NSDictionary *)launchOptions;- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions;

根据苹果官方的demo我们需要做的是:
在appDelegate中创建一个实例变量或者属性

@property (nonatomic, strong) UIApplicationShortcutItem *launchedShortcutItem;

在appDelegate中创建一个方法,并在其中写入如下代码

- (BOOL)handleShortcutItems:(UIApplicationShortcutItem *)shortcutItem {BOOL handled = NO;if (shortcutItem.type == nil) {    return NO;}if (![shortcutItem.type isKindOfClass:[NSString class]]) {    return NO;}//判断类型if ([shortcutItem.type isEqualToString:@"CQTouch"]) {    handled = YES;    //你想执行的指定操作    TableViewController *viewController = [[TableViewController alloc] init];    UINavigationController *nav = (UINavigationController*)self.window.rootViewController;    [nav pushViewController:viewController animated:YES];}return handled;}

接着在接收从shortcutItem的方法中写入

- (void)application:(UIApplication *)application performActionForShortcutItem:(UIApplicationShortcutItem *)shortcutItem completionHandler:(void (^)(BOOL))completionHandler {BOOL x = [self handleShortcutItems:shortcutItem];completionHandler(x);}

再然后在下面方法中写入

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {UIApplicationShortcutItem *shortcutItem = [launchOptions valueForKey:UIApplicationLaunchOptionsShortcutItemKey];if (shortcutItem) {    _launchedShortcutItem = shortcutItem;    return NO;}return YES;}

最后在程序成为Active的状态时写入

- (void)applicationDidBecomeActive:(UIApplication *)application {[self handleShortcutItems:_launchedShortcutItem];_launchedShortcutItem = nil;}

至此,程序便能够从主屏幕的快捷方式进入app内部指定的操作。来分析一下这个方法的流程,两种情况:
第一种,程序未启动时;未启动时程序执行会先执行- (BOOL)application:(UIApplication )application didFinishLaunchingWithOptions:(NSDictionary )launchOptions;方法,在该方法中我们可以通过读取launchOptions中键名为UIApplicationLaunchOptionsShortcutItemKey的值,来获取shortcutItem,如果获取的存在,那么就return NO; 前面说过返回否就不会执行,shortcutItem的委托方法;接着程序变为active状态,那么就会执行[selfhandleShortcutItems:_launchedShortcutItem] 此时就会进入到我们写的方法,执行相应的操作,完成后会将属性launchedShortcutItem置为nil;
第二种,程序已经在后台;点击shortcutItem就会触发委托方法,在委托方法中执行了[self handleShortcutItems:shortcutItem],也就是说采取了特定操作,接着app进入active状态,执行[selfhandleShortcutItems:_launchedShortcutItem],因为此时属性launchedShortcutItem为nil,就会迅速返回nil,也完成了特定操作。

但是肯定会有人想,那么直接在触发shortcutItem程序所执行的委托方法中执行判断和相应操作行不行呢?也就是说省略掉其他三个地方的操作,经过我的测试发现程序也能够正常从shortcutItem运行,因此我未能理解到苹果爸爸这样做的奥义所在,我也未能够理解点击shortcutItem所执行的委托方法中的completionHandler(x)。

在研究的过程中我有一个疑问,如果我连续多次使用主屏幕快捷键功能会怎么样呢?按照之前的代码操作,一定是push出很多viewController这样未免有些不精致;于是我掏出手机检测了一些app是否存在这些问题,经过我的检测QQ、贴吧等都存在这种问题;系统的应用以及微信和极少的三方应用会处理这个问题,不过这个问题也只是处女座的受不了,还有不一定有人这么用。

(由于博客篇幅问题,剩下的在下一篇中)

1 0