最近产品在新需求中加入了对3D Touch 和 Widget的要求,虽然都不是什么新鲜的玩意了,但是真用起来还是有一些坑,下面就是自己此次开发过程的详细总结,以供参考。
3D Touch
自从iPhone 6s+,iOS9+加入了3D Touch功能之后,产品经理们又多了一个展示自己才华的平台,这不,在之前迟迟没有相关需求的前提下,是“祸”总是躲不过的。此次产品要求我们要实现一个类似下图这样的功能,相信是大家最常都会遇到的需求之一。
一、常见使用场景包括:
- 快捷功能小菜单
- 预览和弹出
- 按压力度感应
而我们此次的任务,就是完成场景一:快捷功能小菜单
二、需求效果图
三、技术简介
苹果的桌面快捷功能菜单最多只支持4个快捷标签,要实现这个功能,苹果提供了两种解决方案:分别是.plist文件配置以及使用代码动态构造,下面分别介绍。
- 文件配置
使用.plist文件配置方法需要了解一下几个key的含义:
/*根节点*/
UIApplicationShortcutItems // 主key,Array类型,整个菜单列表的根目录。(必填)
/*菜单选项(必填部分)*/
UIApplicationShortcutItemTitle // 标题,菜单选项对应的标题。(必填)
UIApplicationShortcutItemType // 类型,字符串类型的唯一符,可用来在主程序中判断当前用户的选择。(必填)
/*菜单选项(选填部分)*/
UIApplicationShortcutItemIconType // 图标类型,选用系统推荐图标(非必填)
UIApplicationShortcutItemIconFile // 自定义图标,图标只支持单色,大小:35px * 35px(非必填)
UIApplicationShortcutItemUserInfo // 字典类,可用来传递需要的参数(非必填)
UIApplicationShortcutItemSubtitle // 副标题(非必填)
- 动态构造
代码构造方式与.plist文件十分相似,只需要知道** UIApplicationShortcutItem**表示一个标签对象,其余参数的含义参考.plist文件构建方法。
- (void)registHomeScreenQuickActions {
// 由于3DTouch仅支持iOS9+,因此需要判断下系统是否支持,以免低版本调用导致崩溃
if ([self respondsToSelector:@selector(traitCollection)]) {
if ([self.traitCollection respondsToSelector:@selector(forceTouchCapability)]) {
if (self.traitCollection.forceTouchCapability == UIForceTouchCapabilityAvailable) {
// 构建标签
UIApplicationShortcutItem *searchItem = [[UIApplicationShortcutItem alloc] initWithType:kSearchNewsShortcutItem localizedTitle:@"搜索" localizedSubtitle:nil icon:[UIApplicationShortcutIcon iconWithType:UIApplicationShortcutIconTypeSearch] userInfo:nil];
UIApplicationShortcutItem *hotNewsItem = [[UIApplicationShortcutItem alloc] initWithType:kHotReadNewsShortcutItem localizedTitle:@"热门新闻" localizedSubtitle:nil icon:[UIApplicationShortcutIcon iconWithType:UIApplicationShortcutIconTypeTime] userInfo:nil];
UIApplicationShortcutItem *subscribeItem = [[UIApplicationShortcutItem alloc] initWithType:kMySubcribeShortcutItem localizedTitle:@"我的订阅" localizedSubtitle:nil icon:[UIApplicationShortcutIcon iconWithType:UIApplicationShortcutIconTypeBookmark] userInfo:nil];
// 加入快捷启动菜单
[UIApplication sharedApplication].shortcutItems = @[searchItem, hotNewsItem, subscribeItem];
}
}
}
}
- 点击处理
/**
* 点击回调(当前应用处于活动状态下)
*/
- (void)application:(UIApplication *)application performActionForShortcutItem:(UIApplicationShortcutItem *)shortcutItem completionHandler:(void(^)(BOOL succeeded))completionHandler {
// 根据应用的UIApplicationShortcutItemType判断当前用户选中的标签
if ([selectItemType isEqualToString:kSearchNewsShortcutItem]) {
// 搜索
} else if ([selectItemType isEqualToString:kHotReadNewsShortcutItem]) {
// 热门新闻
} else if ([selectItemType isEqualToString:kMySubcribeShortcutItem]) {
// 订阅
}
if (completionHandler) completionHandler(YES);
}
/**
* 点击回调(在应用还没有启动的状态下)
*/
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
// 根据应用的UIApplicationShortcutItemType判断当前用户选中的标签
if ([selectItemType isEqualToString:kSearchNewsShortcutItem]) {
// 搜索
} else if ([selectItemType isEqualToString:kHotReadNewsShortcutItem]) {
// 热门新闻
} else if ([selectItemType isEqualToString:kMySubcribeShortcutItem]) {
// 订阅
}
}
写在最后
代码动态注册的方法一般写在rootViewController的viewDidLoad方法中,当然也可以写在AppDelegate中的application:didFinishLaunchingWithOptions:中,具体写在哪里,可根据自己的情况而定,个人觉得写在rootViewController是比较理想的位置。
如果是在旧项目中加入该新功能,我并不认为直接插入这段代码是个很好的选择,因此我选用的是扩展的方式,给rootViewController加入一个对3D Touch功能支持的扩展,我认为是更好的选择。
关于3D Touch的更多功能以及Widget相关开发稍后更新。
参考
Take Advantage of 3D Touch
苹果核 - 浅谈3D Touch(1) -- Home screen quick action
跟着官方文档学习3D Touch
在iOS9中使用3D Touch