本文主要讲解3DTouch各种场景下的开发方法,开发主屏幕应用icon上的快捷选项标签(Home Screen Quick Actions),静态设置 UIApplicationShortcutItem ,动态添加、修改UIApplicationShortcutItem,peek和pop的实现。

一、3DTouch开发准备工作(让模拟器也支持 3DTouch 的解决办法)

需要支持3DTouch的设备,如iPhone6s或以上、iOS9或以上、Xcode7或以上,估计很多和我一样的屌丝还没有iPhone6s,别怕,github上有人为我们提供了这样的一个插件,可以让我们在模拟器上进行3D Touch的效果测试。 https://github.com/DeskConnect/SBShortcutMenuSimulator

安装和使用git主页里介绍的很清楚,只有一点需要注意,如果电脑中装有Xcode6和Xcode7两个版本,那个Xcode的编译路径,需要做如下修改。( Xcode2.app是你Xcode7版本的名字 )

sudo xcode-select -switch /Applications/Xcode2.app/Contents/Developer/

二、主屏幕 按压应用图标展示快捷选项 ( Home Screen Quick Actions )

应用最多有4个快捷选项标签, iOS9为我们提供了2种方式来开发按压应用图标展示快捷选项功能(Home Screen Quick Actions)。

1.静态标签

打开我们项目的plist文件,添加如下项(选择框中并没有,需要我们手工敲上去)

UIApplicationShortcutItems:数组中的元素就是我们的那些快捷选项标签。

UIApplicationShortcutItemTitle:标签标题(必填)

UIApplicationShortcutItemType:标签的唯一标识 (必填)

UIApplicationShortcutItemIconType:使用系统图标的类型,如搜索、定位、home等(可选)

UIApplicationShortcutItemIcon File:使用项目中的图片作为标签图标 (可选)

UIApplicationShortcutItemSubtitle:标签副标题 (可选)

UIApplicationShortcutItemUserInfo:字典信息,如传值使用 (可选)

2.动态标签

在AppDelegate.m文件中加如下代码:

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {

    UIStoryboard *storyboard = [UIStoryboard storyboardWithName:@"Main" bundle:nil];
ViewController *mainView = [storyboard instantiateViewControllerWithIdentifier:@"mainController"];
UINavigationController *mainNav = [[UINavigationController alloc] initWithRootViewController:mainView];
self.window.rootViewController = mainNav;
[self.window makeKeyAndVisible]; //创建应用图标上的3D touch快捷选项
[self creatShortcutItem]; UIApplicationShortcutItem *shortcutItem = [launchOptions valueForKey:UIApplicationLaunchOptionsShortcutItemKey];
//如果是从快捷选项标签启动app,则根据不同标识执行不同操作,然后返回NO,防止调用- (void)application:(UIApplication *)application performActionForShortcutItem:(UIApplicationShortcutItem *)shortcutItem completionHandler:(void (^)(BOOL))completionHandler
if (shortcutItem) {
//判断先前我们设置的快捷选项标签唯一标识,根据不同标识执行不同操作
if([shortcutItem.type isEqualToString:@"com.mycompany.myapp.one"]){
NSArray *arr = @[@"hello 3D Touch"];
UIActivityViewController *vc = [[UIActivityViewController alloc]initWithActivityItems:arr applicationActivities:nil];
[self.window.rootViewController presentViewController:vc animated:YES completion:^{
}];
} else if ([shortcutItem.type isEqualToString:@"com.mycompany.myapp.search"]) {//进入搜索界面
SearchViewController *childVC = [storyboard instantiateViewControllerWithIdentifier:@"searchController"];
[mainNav pushViewController:childVC animated:NO];
} else if ([shortcutItem.type isEqualToString:@"com.mycompany.myapp.share"]) {//进入分享界面
SharedViewController *childVC = [storyboard instantiateViewControllerWithIdentifier:@"sharedController"];
[mainNav pushViewController:childVC animated:NO];
}
return NO;
}
return YES;
} //创建应用图标上的3D touch快捷选项
- (void)creatShortcutItem {
//创建系统风格的icon
UIApplicationShortcutIcon *icon = [UIApplicationShortcutIcon iconWithType:UIApplicationShortcutIconTypeShare]; // //创建自定义图标的icon
// UIApplicationShortcutIcon *icon2 = [UIApplicationShortcutIcon iconWithTemplateImageName:@"分享.png"]; //创建快捷选项
UIApplicationShortcutItem * item = [[UIApplicationShortcutItem alloc]initWithType:@"com.mycompany.myapp.share" localizedTitle:@"分享" localizedSubtitle:@"分享副标题" icon:icon userInfo:nil]; //添加到快捷选项数组
[UIApplication sharedApplication].shortcutItems = @[item];
}

效果图:

3.点击快捷选项标签进入应用的响应

在AppDelegate.m文件中加如下代码:

//如果app在后台,通过快捷选项标签进入app,则调用该方法,如果app不在后台已杀死,则处理通过快捷选项标签进入app的逻辑在- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions中
- (void)application:(UIApplication *)application performActionForShortcutItem:(UIApplicationShortcutItem *)shortcutItem completionHandler:(void (^)(BOOL))completionHandler { UIStoryboard *storyboard = [UIStoryboard storyboardWithName:@"Main" bundle:nil];
ViewController *mainView = [storyboard instantiateViewControllerWithIdentifier:@"mainController"];
UINavigationController *mainNav = [[UINavigationController alloc] initWithRootViewController:mainView];
self.window.rootViewController = mainNav;
[self.window makeKeyAndVisible]; //判断先前我们设置的快捷选项标签唯一标识,根据不同标识执行不同操作
if([shortcutItem.type isEqualToString:@"com.mycompany.myapp.one"]){
NSArray *arr = @[@"hello 3D Touch"];
UIActivityViewController *vc = [[UIActivityViewController alloc]initWithActivityItems:arr applicationActivities:nil];
[self.window.rootViewController presentViewController:vc animated:YES completion:^{
}];
} else if ([shortcutItem.type isEqualToString:@"com.mycompany.myapp.search"]) {//进入搜索界面
SearchViewController *childVC = [storyboard instantiateViewControllerWithIdentifier:@"searchController"];
[mainNav pushViewController:childVC animated:NO];
} else if ([shortcutItem.type isEqualToString:@"com.mycompany.myapp.share"]) {//进入分享界面
SharedViewController *childVC = [storyboard instantiateViewControllerWithIdentifier:@"sharedController"];
[mainNav pushViewController:childVC animated:NO];
} if (completionHandler) {
completionHandler(YES);
}
}

4.修改UIApplicationShortcutItem

//获取第0个shortcutItem
UIApplicationShortcutItem *shortcutItem0 = [[UIApplication sharedApplication].shortcutItems objectAtIndex:0];
//将shortcutItem0的类型由UIApplicationShortcutItem改为可修改类型UIMutableApplicationShortcutItem
UIMutableApplicationShortcutItem * newShortcutItem0 = [shortcutItem0 mutableCopy];
//修改shortcutItem的标题
[newShortcutItem0 setLocalizedTitle:@"按钮1"];
//将shortcutItems数组改为可变数组
NSMutableArray *newShortcutItems = [[UIApplication sharedApplication].shortcutItems mutableCopy];
//替换原ShortcutItem
[newShortcutItems replaceObjectAtIndex:0 withObject:newShortcutItem0];
[UIApplication sharedApplication].shortcutItems = newShortcutItems;

三、peek(展示预览)和pop(跳页至预览的界面)

1. 首先给view注册3DTouch的peek(预览)和pop功能,我这里给cell注册 3DTouch的peek(预览)和pop功能

-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"myCell"];
if (cell == nil) {
cell = [[UITableViewCell alloc]initWithStyle:UITableViewCellStyleDefault reuseIdentifier:@"myCell"];
}
cell.textLabel.text = _myArray[indexPath.row];
if (self.traitCollection.forceTouchCapability == UIForceTouchCapabilityAvailable) {
NSLog(@"3D Touch 可用!");
//给cell注册3DTouch的peek(预览)和pop功能
[self registerForPreviewingWithDelegate:self sourceView:cell];
} else {
NSLog(@"3D Touch 无效");
}
return cell;
}

2.需要继承协议UIViewControllerPreviewingDelegate

3.实现UIViewControllerPreviewingDelegate方法

//peek(预览)
- (nullable UIViewController *)previewingContext:(id <UIViewControllerPreviewing>)previewingContext viewControllerForLocation:(CGPoint)location
{
//获取按压的cell所在行,[previewingContext sourceView]就是按压的那个视图
NSIndexPath *indexPath = [_myTableView indexPathForCell:(UITableViewCell* )[previewingContext sourceView]]; //设定预览的界面
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:@"Main" bundle:nil];
SearchViewController *childVC = [storyboard instantiateViewControllerWithIdentifier:@"searchController"];
childVC.preferredContentSize = CGSizeMake(0.0f,500.0f);
childVC.str = [NSString stringWithFormat:@"我是%@,用力按一下进来",_myArray[indexPath.row]]; //调整不被虚化的范围,按压的那个cell不被虚化(轻轻按压时周边会被虚化,再少用力展示预览,再加力跳页至设定界面)
CGRect rect = CGRectMake(0, 0, self.view.frame.size.width,40);
previewingContext.sourceRect = rect; //返回预览界面
return childVC;
} //pop(按用点力进入)
- (void)previewingContext:(id <UIViewControllerPreviewing>)previewingContext commitViewController:(UIViewController *)viewControllerToCommit {
[self showViewController:viewControllerToCommit sender:self];
}

效果图:( 当用户按下时cell周边会虚化,增加压力达到一定值会弹出设定的预览界面,继续增加力按压会跳页至预览界面 )

4.打开预览的视图的.m文件,我这里是 SearchViewController .m中加上如下代码:

- (NSArray<id<UIPreviewActionItem>> *)previewActionItems {
// setup a list of preview actions
UIPreviewAction *action1 = [UIPreviewAction actionWithTitle:@"Aciton1" style:UIPreviewActionStyleDefault handler:^(UIPreviewAction * _Nonnull action, UIViewController * _Nonnull previewViewController) {
NSLog(@"Aciton1");
}]; UIPreviewAction *action2 = [UIPreviewAction actionWithTitle:@"Aciton2" style:UIPreviewActionStyleDefault handler:^(UIPreviewAction * _Nonnull action, UIViewController * _Nonnull previewViewController) {
NSLog(@"Aciton2");
}]; UIPreviewAction *action3 = [UIPreviewAction actionWithTitle:@"Aciton3" style:UIPreviewActionStyleDefault handler:^(UIPreviewAction * _Nonnull action, UIViewController * _Nonnull previewViewController) {
NSLog(@"Aciton3");
}]; NSArray *actions = @[action1,action2,action3]; // and return them (return the array of actions instead to see all items ungrouped)
return actions;
}

效果图:(当弹出预览时,上滑预览视图,出现预览视图中快捷选项)

这个方法在 - (NSArray> *)previewActionItems  中返回action 的数组

有趣的是 如果我们对action 继续包装一个数组 还是可以的,上代码:

NSMutableArray *allActions = [NSMutableArray array];
for (int i = ; i < DATA.count; i ++) {
UIPreviewAction *action = [UIPreviewAction actionWithTitle:DATA[i] style:i % handler:^(UIPreviewAction * _Nonnull action, UIViewController * _Nonnull previewViewController) {
NSLog(@"Jump into---%@",previewViewController);
CustomNaviViewController *naviVC = (CustomNaviViewController*)[UIApplication sharedApplication].delegate.window.rootViewController;
[naviVC pushViewController:previewViewController animated:YES];
[self setViewIndex:i];
}];
[allActions addObject:action];
} UIPreviewActionGroup *group = [UIPreviewActionGroup actionGroupWithTitle:@"查看全部" style:UIPreviewActionStyleDestructive actions:allActions];

这里要说明一下的是,UIPreviewActionItem作为方法

- (NSArray<id<UIPreviewActionItem>> *)previewActionItems

的返回值,UIPreviewAction、UIPreviewActionGroup都可以作为返回值处理。

四、3DTouch压力值的运用

直接上图、上代码更直观,注释也很清楚,这是我的SearchViewController界面。

直接在SearchViewController.m加这个方法即可,按压SearchViewController中的任何视图都会调用这个方法

//按住移动or压力值改变时的回调
-(void)touchesMoved:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event {
NSArray *arrayTouch = [touches allObjects];
UITouch *touch = (UITouch *)[arrayTouch lastObject];
//通过tag确定按压的是哪个view,注意:如果按压的是label,将label的userInteractionEnabled属性设置为YES
if (touch.view.tag == 105) {
NSLog(@"move压力 = %f",touch.force);
//红色背景的label显示压力值
_lbForce.text = [NSString stringWithFormat:@"压力%f",touch.force];
//红色背景的label上移的高度=压力值*100
_bottom.constant = ((UITouch *)[arrayTouch lastObject]).force * 100;
}
}

好了,用不同力度按压那个蓝色背景的label,感受一下力度的变化吧,会看到随着力度的变化红色背景的label会上下移动。

源码: https://github.com/zhanglinfeng/Demo3DTouch.git

来自: http://www.cnblogs.com/zhanglinfeng/p/5133939.html

链接:

iOS9新特性 3DTouch 开发教程全解(含源码

iOS9 3D touch 适配开发

iOS9新特性 3DTouch 开发教程全解(含源码)

iOS 3D Touch实践的更多相关文章

  1. iOS 3D Touch 适配开发

    3D Touch的主要应用 文档给出的应用介绍主要有两块: 1.A user can now press your Home screen icon to immediately access fun ...

  2. iOS 3D Touch功能 3 -备

    新的触摸体验——iOS9的3D Touch 一.引言 二.在模拟器上学习和测试3D Touch 附.SBShortcutMenuSimulator的安装和使用 三.3D Touch的主要应用 四.3D ...

  3. iOS 3D Touch功能

    新的触摸体验——iOS9的3D Touch 一.引言 在iphone6s问世之后,很多果粉都争先要体验3D Touch给用户带来的额外维度上的交互,这个设计之所以叫做3D Touch,其原理上是增加了 ...

  4. iOS 3D touch 使用技巧

    第一个 在桌面中3d Touch 打开菜单 由于本人纯属代码党,本次实现方法也只使用代码实现 到达到这个效果并不难,只需要在appdelegate中实现以下代码即可 ,当然也有缺点,就是这个app没运 ...

  5. ios 3D Touch功能的实现

    ios9中3D Touch功能是一个新的亮点,这个方便快捷的功能实现也比较简单,废话不多说直接上代码, 一.3D Touch功能添加分为两种(1).静态标签 (2).动态标签 (1).静态添加 这个方 ...

  6. 关于iOS 3D touch 指纹验证的随笔

    file:///Users/OWen/Desktop/3DTouch.png 随着iOS系统不断的更新迭代,苹果总会推出一些新的功能,今天就研究了一下iOS8之后推出的指纹验证的功能,然后写了一个小d ...

  7. 3D Touch开发全面教程之Peek and Pop - 预览和弹出

    ## 3D Touch开发全面教程之Peek and Pop - 预览和弹出 --- ### 了解3D Touch 在iPhone 6s和iPhone 6s Plus中Apple引入了3D Touch ...

  8. 在iOS9 中使用3D Touch

    iOS9提供了四类API( Home Screen Quick Action . UIKit Peek & Pop . WebView Peek & Pop 和 UITouch For ...

  9. iOS开发--3D Touch的基本使用

    1.桌面快捷菜单项 效果如图: 桌面快捷菜单 点击之后的效果如图: 点击桌面快捷菜单的效果 接下来看下具体实现:1).在-application:didFinishLaunchingWithOptio ...

随机推荐

  1. 【精粹系列】Mysql精粹

    关于Mysql整理的需要记忆和熟练掌握的内容 1.查询数据表的信息(比如有多少行数据): show table status like 'tab_User' -- 数据表中的数量   2. 使用 ex ...

  2. Java程序员应该知道的10个调试技巧

    试可以帮助识别和解决应用程序缺陷,在本文中,作者将使用大家常用的的开发工具Eclipse来调试Java应用程序.但这里介绍的调试方法基本都是通用的,也适用于NetBeans IDE,我们会把重点放在运 ...

  3. java web学习总结(二十一) -------------------模拟Servlet3.0使用注解的方式配置Servlet

    一.Servlet的传统配置方式 在JavaWeb开发中, 每次编写一个Servlet都需要在web.xml文件中进行配置,如下所示: 1 <servlet> 2 <servlet- ...

  4. Atitit.提升 升级类库框架后的api代码兼容性设计指南

    Atitit.提升 升级类库框架后的api代码兼容性设计指南 1. 增加api直接增加,版本号在注释上面增加1 2. 废弃api,使用主见@dep1 3. 修改api,1 4. 修改依赖import, ...

  5. jQuery中的事件处理

    1.页面载入完毕响应事件所谓页面载入完毕是指DOM元素载入就绪了,能够被读取和操作了.①jQuery中的$(doucument).ready()事件ready(fn)是jQuery事件模块中最重要的一 ...

  6. Sharepoint学习笔记—习题系列--70-573习题解析 -(Q142-Q143)

    Question 142You have a Feature that contains an image named ImageV1.png.You plan to create a new ver ...

  7. iOS多线程之3.NSThread的线程间通信

      我们把一些耗时操作放在子线程,例如下载图片,但是下载完毕我们不能在子线程更新UI,因为只有主线程才可以更新UI和处理用户的触摸事件,否则程序会崩溃.此时,我们就需要把子线程下载完毕的数据传递到主线 ...

  8. SSH之免密码登录

    我的虚拟机: 192.168.91.130  test1 192.168.91.131  test2 192.168.91.132  test3 1.首先在test1上生成秘钥对 之后会生成.shh/ ...

  9. 《java JDK7 学习笔记》之接口与多态

    1.对于"定义行为"也就是接口,可以使用interface关键字定义,接口中的方法不能操作,直接标示为abstract,而且一定是public修饰的. 类要操作接口,必须使用imp ...

  10. Oracle索引梳理系列(五)- Oracle索引种类之表簇索引(cluster index)

    版权声明:本文发布于http://www.cnblogs.com/yumiko/,版权由Yumiko_sunny所有,欢迎转载.转载时,请在文章明显位置注明原文链接.若在未经作者同意的情况下,将本文内 ...