本文主要讲解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. JVM-绘图展现字节码执行引擎执行过程

    在我的上一篇博客JVM-String比较-字节码分析中介绍了String字符串比较的原因,借着分析字节码的机会,我这篇博客将会绘图展现方法内部字节码执行过程. 话不多说,贴上我们将要分析的Java方法 ...

  2. PHP程序员的技术成长规划

    按照了解的很多PHP/LNMP程序员的发展轨迹,结合个人经验体会,抽象出很多程序员对未来的迷漫,特别对技术学习的盲目和慌乱,简单梳理了这个每个阶段PHP程序员的技术要求,来帮助很多PHP程序做对照设定 ...

  3. 【工业串口和网络软件通讯平台(SuperIO)教程】六.二次开发导出数据驱动

    SuperIO相关资料下载:http://pan.baidu.com/s/1pJ7lZWf 1.1    导出数据接口的作用 在数据集成系统项目中,要么是自已集成其他厂家的设备,要么是其他厂家集成自己 ...

  4. 关于ArcGIS的Web 3D GIS问答

    以下问答基于ArcGIS 10.4版本,涉及的软件有 ArcGIS for Server ArcGIS for Desktop ArcGIS Pro 1.3 Esri Drone2Map 1 支持B/ ...

  5. spring-boot-framework 如何自动将对象返回成json格式

    使用srping-rest-mvc 的时候只要在工程的classpath中包含jackson的2.x版本,就可以不用自己做json格式的转换了. 如在你的pom文件中加入以下的依赖: <depe ...

  6. IOS开发基础知识--碎片1

    一:NSString与NSInteger的互换 NSInteger转化NSString类型:[NSString stringWithFormat: @"%d", NSInteger ...

  7. iOS 数字滚动 类似于老 - 虎- 机的效果

    效果图 具体实现代码如下 ZCWScrollNumView.h文件 #import <UIKit/UIKit.h> typedef enum { ZCWScrollNumAnimation ...

  8. python之import子目录文件

    问题:   在pre_tab.py文件下: print("AA") from test.te import login1 login1() from test.te import ...

  9. h5滑动方向、手机拖动层

    做h5时需对手指滑动方向判断及拖动浮动层,本文代码适用于手机端h5页面,pc页面可使用onMouseDown.onMouseUp.onMouseMove.(本方法仅为功能实现原理和演示,可根据自己的需 ...

  10. ORACLE计算表引占用空间大小

    在ORACLE数据库中,如何计算一个表所占用的存储空间呢?我们可以通过系统视图DBA_SEGMENTS.USER_SEGMETNS.DBA_TABLES来查看一个表所占空间的大小,如下所示:   SE ...