iOS9提供了四类API( Home Screen Quick ActionUIKit Peek & PopWebView Peek & PopUITouch Force Properties )用于操作3D Touch。不过无论使用哪一种API,首先需要做的事情是检查3D Touch是否可用。

检测是否支持3D Touch

在iOS9中提供如下的接口用于检查设备是否支持3D Touch:

@property(nonatomic, readonly) UIForceTouchCapability forceTouchCapability;

其中 UIForceTouchCapability 是一个枚举类型,具体的描述情况如下:

  • UIForceTouchCapability

    • UIForceTouchCapabilityUnknown //3D Touch检测失败
    • UIForceTouchCapabilityUnavailable //3D Touch不可用
    • UIForceTouchCapabilityAvailable //3D Touch可用

这3个枚举值就是我们来判断设备是否开启3D Touch功能,可以在UIViewController生命周期的viewWillAppear中做如下判断:

if (self.traitCollection.forceTouchCapability == UIForceTouchCapabilityAvailable) {
//do something
}

当然在生命周期内,如果用户有意修改了设备的3D Touch功能,我们还有一个地方来重新检测:

- (void)traitCollectionDidChange:(UITraitCollection *)previousTraitCollection {
//do something
}

Home Screen Quick Action

创建Quick Action有两种方式:静态和动态

①以静态方式创建

静态创建的方式是在Info.plist文件中进行声明的

<key>UIApplicationShortcutItems</key>
<array>
<dict>
<key>UIApplicationShortcutItemIconType</key>
<string>UIApplicationShortcutIconTypeShare</string>
<key>UIApplicationShortcutItemTitle</key>
<string>分享</string>
<key>UIApplicationShortcutItemType</key>
<string>UITouchText.share</string>
<key>UIApplicationShortcutItemUserInfo</key>
<dict>
<key>key1</key>
<string>value1</string>
</dict>
</dict>
<dict>
<key>UIApplicationShortcutItemType</key>
<string>com.devzeng.about</string>
<key>UIApplicationShortcutItemTitle</key>
<string>关于我们</string>
<key>UIApplicationShortcutItemSubtitle</key>
<string>这是关于我们</string>
<key>UIApplicationShortcutItemIconFile</key>
<string>icon_about.png</string>
<key>UIApplicationShortcutItemUserInfo</key>
<dict>
<key>scheme</key>
<string>devzeng://about</string>
</dict>
</dict>
</array>

②以动态方式创建

动态创建是在程序初始化的时候用代码动态添加。 UIApplication 对象多了一个支持快捷方式的数组(shortcutItems), 如果需要增加快捷方式,可以赋值给shortcutItems属性。

在方法中 - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions

 UIApplicationShortcutIcon *icon = [UIApplicationShortcutIcon iconWithTemplateImageName:@""];
UIApplicationShortcutItem *item = [[UIApplicationShortcutItem alloc] initWithType:@"search22"
localizedTitle:@"search22"
localizedSubtitle:@"0abc"
icon:icon
userInfo:nil];
application.shortcutItems = @[item];

说明:

1)系统限制每个App最多能够显示4个Action Item,其中包括静态方式和动态方式进行创建的;

2)如果静态和动态方式同时使用的时候,给UIApplication的shortcutItems赋值的时候不会覆盖

3)注,定义的图标 是35x35 的单色图标

当app在后台的时候UIApplication提供了一个回调方法,如下

- (void)application:(UIApplication *)application performActionForShortcutItem:(UIApplicationShortcutItem *)shortcutItem
completionHandler:(void(^)(BOOL succeeded))completionHandler{
//判断先前我们设置的唯一标识
if([shortcutItem.type isEqualToString:@"UITouchText.share"]){
NSArray *arr = @[@"hello 3D Touch"];
UIActivityViewController *vc = [[UIActivityViewController alloc]initWithActivityItems:arr applicationActivities:nil];
//设置当前的VC 为rootVC
[self.window.rootViewController presentViewController:vc animated:YES completion:^{
}];
}
else if ([shortcutItem.type isEqualToString:@"UITouchText.search"])
{
UIAlertView *alertView = [[UIAlertView alloc]initWithTitle:@"温馨提示" message:@"好想你" delegate:nil cancelButtonTitle:@"cancel" otherButtonTitles:@"sure", nil];
[alertView show];
}
else if ([shortcutItem.type isEqualToString:@"UITouchText.look"])
{
UIActionSheet *sheet = [[UIActionSheet alloc]initWithTitle:@"温馨提示" delegate:nil cancelButtonTitle:@"cancel" destructiveButtonTitle:@"删除" otherButtonTitles:@"更多", nil];
[sheet showInView:self.window];
}
else if ([shortcutItem.type isEqualToString:@"UITouchText.compose"])
{
NSLog(@"UITouchText.compose");
}
}

我们依据这个回调中的shortcutItem的type和userinfo来做出不同的事件处理,而最后的completionHandler在API的说明中我们看到当应用并非在后台,而是直接重新开进程的时候,直接返回No,那么这个时候,我们的回调会放在

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

UIApplication又给我们一个从launchOptions中获取这个shortcutItem的key(UIApplicationLaunchOptionsShortcutItemKey)

UIApplicationShortcutItem *item = [launchOptions valueForKey:UIApplicationLaunchOptionsShortcutItemKey];
//根据不同的Action响应不同的事件

Peek and Pop(预览和详阅)

如同使用放大镜拉近视角,预览(Peek)内容(照片、视频)让你可以获得更多信息而不需要加载完整内容。

Instagram首先将Peek功能添加到了小图片和视频上。

Peek(预 览)和Pop(详阅)相关的API为UIViewControllerPreviewingDelegate,它通过view来注册。在 Instagram中,我们只将其注册到可以接受到touch事件的controller的view上。当3D touch事件发生时,delegate来检测view中的哪个对象被点击。

如果delegate判断有Peek(预览)动作发生,它仍需要处理两件事情:1. 设置预览动作发生的view的rect;2. 返回展示的viewcontroller。

当3D touch发生时,会传递给你context信息,包含源view和点击发生的point。自定义的delegate需要通过这个point映射到一个view,然后查找到需要预览的数据。

大多数的Instagram功能基于UICollectionView和UITableView实现。这两者在数据和UI间对应方面都有不错的API支持。

- (UIViewController *)previewingContext:(id)previewingContext viewControllerForLocation:(CGPoint)location {
UICollectionView *collectionView = (UICollectionView *)[previewingContext sourceView];
NSIndexPath *indexPath = [collectionView indexPathForItemAtPoint:location]; if (indexPath) {
IGPostCell *cell = [collectionView cellForItemAtIndexPath:indexPath];
[previewingContext setSourceRect:cell.frame]; IGPost *post = self.feedController.posts[indexPath.row];
IGThumbnailPreviewController *controller = [[IGThumbnailPreviewController alloc] initWithPost:post];
return controller;
} // no peek
return nil;
}

将预览相关的API和现有的view和功能结合后,查看Instagram照片和视频变的异常简单

我们为header和comment中的用户名添加了查看信息的功能。用来预览用户信息的delegate和显示照片/视频的实现类似:

  • 使用3D touch点击的location和查找到的index path找到对应的cell。

  • 将点击的point关联转换到cell中的textview上。

  • 通过该point获取到text view中的attributed string的属性。

  • 如果找到了用户名称的属性,则返回IGUserPreviewController。

将这些实现串起来,看起来就像这样:

混合内容展示

Instagram中的activity feed功能包含了用户的tag和缩略图。我们之前分别创建过UIViewControllerPreviewingDelegate的对象,用来显示这两种内容。这里我们需要把这些组合在一起。

拷贝已有代码到新的delegate中的做法并不明智。我们选择使用composition模式来组合profile和post展示的delegate代码,这样创建一个新的对象,只需要传递touch 事件即可。

@interface IGUserThumbnailPreviewingHandler : NSObject
@property (nonatomic, strong) IGUserPreviewingHandler *userDelegate;
@property (nonatomic, strong) IGFeedThumbnailPreviewingHandler *thumbnailDelegate;
@end - (UIViewController *)previewingContext:(idUIViewControllerPreviewing>)previewingContext viewControllerForLocation:(CGPoint)location {
id controller = [self.thumbnailDelegate previewingContext:previewingContext viewControllerForLocation:location];
if (!controller) {
controller = [self.userDelegate previewingContext:previewingContext viewControllerForLocation:location];
}
return controller;
}

用来显示预览的controller只是UIViewController的子类,在某些特别属性上有所不同。

一开始,controller完全无法交互,你无法在上面点击按钮或添加自定义手势。这里我们需要提供遵循UIPreviewActionItem协议的对象组成的数组。在Instagram中,我们只用UIPreviewActions。

这些功能看起来很像UIAlertController的action item。

在整个Instagram程序中,我们只在需要的时候加载数据,并缓存以备以后使用。这样做既节省了网络等待的时间,又不会浪费用户的带宽。

有 时,当预览用户profile时,我们获取的数据还不足以用来显示最新照片或关注者数量。预览用的view controller仍然会调用viewDidLoad, viewWillAppear:和其他UIViewController事件。在其中可以获取网络数据并更新UI。

最后,我们发现可以通过修改controller的preferredContentSize来调整预览视图的大小,即便是controller已经展示了,这样的改变仍可生效。不过,这个属性无法作用于动画中。

ios 3D Touch功能的实现

参考:http://git.devzeng.com/blog/ios9-3d-touch.html?utm_source=tuicool&utm_medium=referral

http://engineering.instagram.com/posts/465414923641286/lessons-learned-with-3D-touch

http://www.cocoachina.com/ios/20151110/14129.html

在iOS9 中使用3D Touch的更多相关文章

  1. iOS9新特性-3D Touch

    本文主要讲解3DTouch各种场景下的开发方法,开发主屏幕应用icon上的快捷选项标签(Home Screen Quick Actions),静态设置 UIApplicationShortcutIte ...

  2. iOS- 指压即达,如何集成iOS9里的3D Touch

    1.前言   随着6S的到来,3DTouch被各大热门APP迅速普及,博主亲自体验后,发现使用便捷性大幅提高,随后自己照着文档,写了个Demo出来,分享给大家,希望能对有需要的朋友提供有一些帮助. 2 ...

  3. 5月8日——iOS中的3D Touch效果

    需要在manifest.json文件中进行配置 需要执行的js代码为: 最终操作效果为 本篇文章主要采用了HTML5+  中的 launcher属性 具体可参照 http://www.html5plu ...

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

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

  5. iOS 3D Touch 适配开发

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

  6. 3D Touch

    一.认识3D Touch   1.硬件和操作系统要求      iPhone 6s或者iPhone 6s Plus      操作系统要求 ios9+ 2.3D Touch的交互效果 QuickAct ...

  7. Swift 玩转 3D Touch 之 Peek & Pop

    什么是3D Touch 3D Touch 是iOS9之后专为 iPhone6s 机型加入的新特性,这一新技术移植于 Mac Book 上的 ForceTouch 更准确地说应该是 ForceTouch ...

  8. 3d touch 应用 2 -备用

    一.引言 在iphone6s问世之后,很多果粉都争先要体验3D Touch给用户带来的额外维度上的交互,这个设计之所以叫做3D Touch,其原理上是增加了一个压力的感触,通过区分轻按和重按来进行不同 ...

  9. iOS 3D Touch功能 3 -备

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

随机推荐

  1. redis命令手册

    Redis 键(key) 命令 命令 描述 Redis DEL 命令 该命令用于在 key 存在是删除 key. Redis Dump 命令 序列化给定 key ,并返回被序列化的值. Redis E ...

  2. 关于JRebel启动tomcat访问上次工程的index.jsp

    检查了一下,原来我把上次配置文件包括JRebel配置文件一起复制过来,用JRebel启动时tomcat访问JRebel配置文件的目录下 这个是我上次文件的路径,把JRebel配置文件删除了,然后 di ...

  3. 字典树Trie树

    摘自大佬博客 https://www.cnblogs.com/TheRoadToTheGold/p/6290732.html 给出n个单词和m个询问1.查询某个前缀是否出现过2.查询某个单词是否出现过 ...

  4. stop-hbase.sh一直处于等待状态

    今天关闭HBase时,输入stop-hbase.sh一直处于等待状态 解决方法: 先输入:hbase-daemon.sh stop master 再输入:stop-hbase.sh就可以关闭HBase ...

  5. 蜻蜓fm面试

    一面: 面试官首先看简历上写了在腾讯的实习,然后就探讨了半天,各种虚拟化的技术.... 说完之后,估计都半小时过去了,然后就又说了一下你用什么语言,你做的东西都比较偏底层呢,然后你对工作有什么要求吗? ...

  6. Android提权原理

    Android的内核就是Linux,所以Android获取root其实和Linux获取root权限是一回事儿. 你想在Linux下获取root权限的时候就是执行sudo或者su,接下来系统会提示你输入 ...

  7. 20155325 Exp2 后门原理与实践

    基础问答 例举你能想到的一个后门进入到你系统中的可能方式? 乱点链接 学电脑小白不正确配置电脑 下载非官网软件 例举你知道的后门如何启动起来(win及linux)的方式? 软件:ncat socat ...

  8. 连接到win2003的远程桌面,客户端要如何操作

    第一步:命令行执行mstsc 第二步:处输入开启了远程桌面功能的计算机IP地址.

  9. Voronoi图与Delaunay三角剖分

    详情请见[ZJOI2018]保镖 题解随笔 - 99 文章 - 0 评论 - 112

  10. source insight之quicker.em宏的使用

    source insight有很多宏可以用,这里介绍的宏是quicker.em这个宏,它是华为的一个员工写的,很实用. 1.安装quicker.em宏 一.打开base这个工程Project-> ...