3D Touch详解

http://blog.csdn.net/victormokai/article/details/49734631

本文出自

http://mokai.github.io/2015/11/3d-touch/

3D Touch最先应用在Apple Watch上面,但叫Force Touch,后在iPhone6s上加入了此特性,并改名3D Touch。值得注意的是目前3D Touch只支持iPhone6S以后的机型,包括现有Xcode7中6s的模拟器也不支持,不过Github上的SBShortcutMenuSimulator项目通过Hack方式已经实现了Quick Actions快捷访问,但不能使用Peek&Pop快速预览。


如果你还不知道3D Touch是什么,可以看看官方宣传视频 

环境

系统环境: iOS9 or later

开发环境: Swift2.0 & Xcode7.1

Demo: 3DTouchDemo【ps没有6s或者6s plus的就不要下载了,下了你也跑不起来,所以赶快去卖肾吧】

效果: 

开始

3D Touch可以分为三种:

  • Quick Actions【可以理解PC桌面的快捷方式】
  • Peek&Pop【应用内快速预览内容】
  • UITouch【自定义3D Touch事件】

Quick Actions 快捷方式

配置Actions可以通过工程Info.plist文件静态配置,也可以在运行时动态添加,两者可以一起使用。

静态配置在Info.plistUIApplicationShortcutItems节点数组下添加相应Actions Item信息

<code class="hljs xml has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;"><span class="hljs-tag" style="color: rgb(0, 102, 102); box-sizing: border-box;"><<span class="hljs-title" style="box-sizing: border-box; color: rgb(0, 0, 136);">key</span>></span>UIApplicationShortcutItems<span class="hljs-tag" style="color: rgb(0, 102, 102); box-sizing: border-box;"></<span class="hljs-title" style="box-sizing: border-box; color: rgb(0, 0, 136);">key</span>></span>
<span class="hljs-tag" style="color: rgb(0, 102, 102); box-sizing: border-box;"><<span class="hljs-title" style="box-sizing: border-box; color: rgb(0, 0, 136);">array</span>></span>
    <span class="hljs-tag" style="color: rgb(0, 102, 102); box-sizing: border-box;"><<span class="hljs-title" style="box-sizing: border-box; color: rgb(0, 0, 136);">dict</span>></span>
        <span class="hljs-tag" style="color: rgb(0, 102, 102); box-sizing: border-box;"><<span class="hljs-title" style="box-sizing: border-box; color: rgb(0, 0, 136);">key</span>></span>UIApplicationShortcutItemIconType<span class="hljs-tag" style="color: rgb(0, 102, 102); box-sizing: border-box;"></<span class="hljs-title" style="box-sizing: border-box; color: rgb(0, 0, 136);">key</span>></span>
        <span class="hljs-tag" style="color: rgb(0, 102, 102); box-sizing: border-box;"><<span class="hljs-title" style="box-sizing: border-box; color: rgb(0, 0, 136);">string</span>></span>UIApplicationShortcutIconTypeSearch<span class="hljs-tag" style="color: rgb(0, 102, 102); box-sizing: border-box;"></<span class="hljs-title" style="box-sizing: border-box; color: rgb(0, 0, 136);">string</span>></span>
        <span class="hljs-tag" style="color: rgb(0, 102, 102); box-sizing: border-box;"><<span class="hljs-title" style="box-sizing: border-box; color: rgb(0, 0, 136);">key</span>></span>UIApplicationShortcutItemTitle<span class="hljs-tag" style="color: rgb(0, 102, 102); box-sizing: border-box;"></<span class="hljs-title" style="box-sizing: border-box; color: rgb(0, 0, 136);">key</span>></span>
        <span class="hljs-tag" style="color: rgb(0, 102, 102); box-sizing: border-box;"><<span class="hljs-title" style="box-sizing: border-box; color: rgb(0, 0, 136);">string</span>></span>搜索<span class="hljs-tag" style="color: rgb(0, 102, 102); box-sizing: border-box;"></<span class="hljs-title" style="box-sizing: border-box; color: rgb(0, 0, 136);">string</span>></span>
        <span class="hljs-tag" style="color: rgb(0, 102, 102); box-sizing: border-box;"><<span class="hljs-title" style="box-sizing: border-box; color: rgb(0, 0, 136);">key</span>></span>UIApplicationShortcutItemType<span class="hljs-tag" style="color: rgb(0, 102, 102); box-sizing: border-box;"></<span class="hljs-title" style="box-sizing: border-box; color: rgb(0, 0, 136);">key</span>></span>
        <span class="hljs-tag" style="color: rgb(0, 102, 102); box-sizing: border-box;"><<span class="hljs-title" style="box-sizing: border-box; color: rgb(0, 0, 136);">string</span>></span>me.mokai.TouchDemo.action.search<span class="hljs-tag" style="color: rgb(0, 102, 102); box-sizing: border-box;"></<span class="hljs-title" style="box-sizing: border-box; color: rgb(0, 0, 136);">string</span>></span>
    <span class="hljs-tag" style="color: rgb(0, 102, 102); box-sizing: border-box;"></<span class="hljs-title" style="box-sizing: border-box; color: rgb(0, 0, 136);">dict</span>></span>
    ...
<span class="hljs-tag" style="color: rgb(0, 102, 102); box-sizing: border-box;"></<span class="hljs-title" style="box-sizing: border-box; color: rgb(0, 0, 136);">array</span>></span></code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li><li style="box-sizing: border-box; padding: 0px 5px;">10</li><li style="box-sizing: border-box; padding: 0px 5px;">11</li><li style="box-sizing: border-box; padding: 0px 5px;">12</li></ul>

动态配置通过UIApplication的shortcutItems添加,shortcutItems是一个UIApplicationShortcutItem数组

<code class="hljs fsharp has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;"><span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">let</span> <span class="hljs-class" style="box-sizing: border-box;"><span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">type</span> =</span> <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"me.mokai.TouchDemo.action.identify"</span>
<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">let</span> title = <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"听歌识别"</span>
<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">let</span> shortcutItem = UIApplicationShortcutItem(<span class="hljs-class" style="box-sizing: border-box;"><span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">type</span>: <span class="hljs-title" style="box-sizing: border-box; color: rgb(102, 0, 102);">type</span>, <span class="hljs-title" style="box-sizing: border-box; color: rgb(102, 0, 102);">localizedTitle</span>: <span class="hljs-title" style="box-sizing: border-box; color: rgb(102, 0, 102);">title</span>,</span>
 localizedSubtitle: nil, icon: UIApplicationShortcutIcon(templateImageName: <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"quick_filter"</span>), userInfo: nil)
application.shortcutItems = [shortcutItem]</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li></ul>

Note

  • Actions的图标可以使用系统预定的也可以自定义图片
  • 对于每个Actions来说type是必须的,它代表着我们从桌面点击Actions进入到应用调用application(application, performActionForShortcutItem:, completionHandler:)时的唯一标识,另外userInfo可以附加每个actions的数据,如最近听歌的歌曲id
  • 当APP启动时,shortcutItems的值是上次动态添加的,如果是第一次启动则为空数组。
  • Actions最多显示4个,优先显示静态Actions,然后剩余个数显示shortcutItems的前几个。

Peek&POP 快速预览

好了,下面介绍本文重头戏,先上效果

Peek窗口的内容其实是目标VC【ps即将要显示的ViewController】的一个实时快照,但它不可以点击。Peek触发阶段有三种:

  • 长按【显示一个焦点视图,触发Peek的源视图高亮,其它视图都处于模糊状态】
  • 轻压【显示Peek窗口,此时如果Peek窗口支持Quick Actions,往上滑会显示Quick Actions菜单,此时的Peek窗口是不可以点击的】
  • 重压 【进入到真正的ViewController】

Peek由一个可响应事件的View触发,默认是关闭的,我们需要通过控制器的registerForPreviewingWithDelegate: sourceView:方法注册,第一个参数为UIViewControllerPreviewingDelegate的代理,Peek触发轻压时会调用其previewingContext:viewControllerForLocation方法,重压时会调用previewingContext:commitViewController:方法。第二个参数为触发Peek事件的源视图

<code class="hljs rust has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;"><span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//注册</span>
registerForPreviewingWithDelegate(<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">self</span>, sourceView: userVCBtn)</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li></ul>
<code class="hljs objectivec has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;"><span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//Delegate</span>
<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//轻压,进入第二阶段,显示Peek窗口</span>
func previewingContext(previewingContext: UIViewControllerPreviewing, var viewControllerForLocation location: <span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">CGPoint</span>) -> <span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">UIViewController</span>? {
    let userVc = <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">self</span><span class="hljs-variable" style="color: rgb(102, 0, 102); box-sizing: border-box;">.storyboard</span>?<span class="hljs-variable" style="color: rgb(102, 0, 102); box-sizing: border-box;">.instantiateViewControllerWithIdentifier</span>(<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"UserViewController"</span>) as! UserViewController
    <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">return</span> userVc;
}
<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//重压,进入第三阶段,显示真正的ViewController</span>
func previewingContext(previewingContext: UIViewControllerPreviewing, commitViewController viewControllerToCommit: <span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">UIViewController</span>) {
    showViewController(viewControllerToCommit, sender: <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">self</span>)
}</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li><li style="box-sizing: border-box; padding: 0px 5px;">10</li></ul>

如果Peek窗口需要Quick Actions菜单,在目标VC中重写previewActionItems方法返回一个UIPreviewActionItem或者一个UIPreviewActionGroup数组就行了。

<code class="hljs coffeescript has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;"><span class="hljs-regexp" style="color: rgb(0, 136, 0); box-sizing: border-box;">//</span>目标VC
lazy <span class="hljs-reserved" style="box-sizing: border-box;">var</span> <span class="hljs-attribute" style="box-sizing: border-box; color: rgb(0, 136, 0);">previewActions</span>: [UIPreviewActionItem] = {
    func previewActionForTitle<span class="hljs-function" style="box-sizing: border-box;"><span class="hljs-params" style="color: rgb(102, 0, 102); box-sizing: border-box;">(title: String, style: UIPreviewActionStyle = .Default)</span> -></span> UIPreviewAction {
        <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">return</span> UIPreviewAction(<span class="hljs-attribute" style="box-sizing: border-box; color: rgb(0, 136, 0);">title</span>: title, <span class="hljs-attribute" style="box-sizing: border-box; color: rgb(0, 136, 0);">style</span>: style) { previewAction, viewController <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">in</span>
            <span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">print</span>(<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"点击了\(title)"</span>) <span class="hljs-regexp" style="color: rgb(0, 136, 0); box-sizing: border-box;">//</span>这里是Actions响应
        }
    }
    <span class="hljs-reserved" style="box-sizing: border-box;">let</span> action1 = previewActionForTitle(<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"关注TA"</span>,<span class="hljs-attribute" style="box-sizing: border-box; color: rgb(0, 136, 0);">style</span>: .Destructive) <span class="hljs-regexp" style="color: rgb(0, 136, 0); box-sizing: border-box;">//</span>显示红色,代表重要Action
    <span class="hljs-reserved" style="box-sizing: border-box;">let</span> action2 = previewActionForTitle(<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"私信TA"</span>)
    <span class="hljs-regexp" style="color: rgb(0, 136, 0); box-sizing: border-box;">//</span>子Actioons
    <span class="hljs-reserved" style="box-sizing: border-box;">let</span> subAction1 = previewActionForTitle(<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"微博"</span>)
    <span class="hljs-reserved" style="box-sizing: border-box;">let</span> subAction2 = previewActionForTitle(<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"好友圈"</span>)
    <span class="hljs-reserved" style="box-sizing: border-box;">let</span> subAction3 = previewActionForTitle(<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"QQ"</span>)
    <span class="hljs-reserved" style="box-sizing: border-box;">let</span> subAction4 = previewActionForTitle(<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"微信"</span>)
    <span class="hljs-reserved" style="box-sizing: border-box;">let</span> groupedActions = UIPreviewActionGroup(<span class="hljs-attribute" style="box-sizing: border-box; color: rgb(0, 136, 0);">title</span>: <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"分享…"</span>, <span class="hljs-attribute" style="box-sizing: border-box; color: rgb(0, 136, 0);">style</span>: .Default, <span class="hljs-attribute" style="box-sizing: border-box; color: rgb(0, 136, 0);">actions</span>: [subAction1, subAction2,subAction3,subAction4] )
    <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">return</span> [action1, action2, groupedActions]
}()
override func previewActionItems<span class="hljs-function" style="box-sizing: border-box;"><span class="hljs-params" style="color: rgb(102, 0, 102); box-sizing: border-box;">()</span> -></span> [UIPreviewActionItem] {
    <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">return</span> previewActions
}</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li><li style="box-sizing: border-box; padding: 0px 5px;">10</li><li style="box-sizing: border-box; padding: 0px 5px;">11</li><li style="box-sizing: border-box; padding: 0px 5px;">12</li><li style="box-sizing: border-box; padding: 0px 5px;">13</li><li style="box-sizing: border-box; padding: 0px 5px;">14</li><li style="box-sizing: border-box; padding: 0px 5px;">15</li><li style="box-sizing: border-box; padding: 0px 5px;">16</li><li style="box-sizing: border-box; padding: 0px 5px;">17</li><li style="box-sizing: border-box; padding: 0px 5px;">18</li><li style="box-sizing: border-box; padding: 0px 5px;">19</li><li style="box-sizing: border-box; padding: 0px 5px;">20</li></ul>
更快速的方法

上面是代码激活Peek的方式,还有更Peek的方式:直接在Storyboard中使用Segue,在Segue属性面板中把Peek & Pop 勾选上就完事了。

使用这种方式指定我们在代码中连注册都不用,所以使用SB的项目适配3D Touch那是分分钟搞定的事,尤其在Xcode7出了Storyboard References后,我大 Swift + Storyboard 组合势必统一iOS界~



好了,有点小激动了,继续回到正文 

在正常情况下,Peek窗口默认显示目标VC的整个View,但在实际应用中,可能会有更多的需求,比如说二个Button Push的是同一个VC,但是需要分别显示不同的Peek窗口。

其实也很简单,我们只需要自定义一个Peek的生命周期扩展就行了,previewingContext:viewControllerForLocation:方法中代表Peek的开始,previewingContext:commitViewController代表Peek的结束,然后在目标VC中重写二个方法就行了

<code class="hljs java has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;"><span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//UIViewController+PeekCycle.swift</span>
<span class="hljs-javadoc" style="color: rgb(136, 0, 0); box-sizing: border-box;">/**
 Peek生命周期
**/</span>
extension UIViewController {
    <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//开始peek,VC为Peek显示做初始化</span>
    func beginPeek(){}
    <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//结束peek,VC为真正显示做初始化</span>
    func endPeek(){}
}</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li><li style="box-sizing: border-box; padding: 0px 5px;">10</li></ul>
<code class="hljs objectivec has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;"><span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//Delegate</span>
func previewingContext(previewingContext: UIViewControllerPreviewing, var viewControllerForLocation location: <span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">CGPoint</span>) -> <span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">UIViewController</span>? {
    let detailVc = <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">self</span><span class="hljs-variable" style="color: rgb(102, 0, 102); box-sizing: border-box;">.storyboard</span>?<span class="hljs-variable" style="color: rgb(102, 0, 102); box-sizing: border-box;">.instantiateViewControllerWithIdentifier</span>(<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"DetailViewController"</span>) as! DetailViewController
    <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//指定Peek窗口类型</span>
    detailVc<span class="hljs-variable" style="color: rgb(102, 0, 102); box-sizing: border-box;">.peekType</span> = <span class="hljs-variable" style="color: rgb(102, 0, 102); box-sizing: border-box;">.Image</span>
    <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//设置Peek的高度</span>
    detailVc<span class="hljs-variable" style="color: rgb(102, 0, 102); box-sizing: border-box;">.preferredContentSize</span> = <span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">CGSize</span>(width: <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0.0</span>, height: <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">320</span>);
    detailVc<span class="hljs-variable" style="color: rgb(102, 0, 102); box-sizing: border-box;">.view</span> <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//先访问一下view,初始化</span>
    detailVc<span class="hljs-variable" style="color: rgb(102, 0, 102); box-sizing: border-box;">.beginPeek</span>() <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//peek开始</span>
    <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">return</span> detailVc;
}
func previewingContext(previewingContext: UIViewControllerPreviewing, commitViewController viewControllerToCommit: <span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">UIViewController</span>) {
    viewControllerToCommit<span class="hljs-variable" style="color: rgb(102, 0, 102); box-sizing: border-box;">.endPeek</span>()  <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//peek结束</span>
    showViewController(viewControllerToCommit, sender: <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">self</span>)
}</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li><li style="box-sizing: border-box; padding: 0px 5px;">10</li><li style="box-sizing: border-box; padding: 0px 5px;">11</li><li style="box-sizing: border-box; padding: 0px 5px;">12</li><li style="box-sizing: border-box; padding: 0px 5px;">13</li><li style="box-sizing: border-box; padding: 0px 5px;">14</li><li style="box-sizing: border-box; padding: 0px 5px;">15</li></ul>
<code class="hljs cs has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;"><span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//目标VC</span>
<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">override</span> func beginPeek() { 
    <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span>(peekType == .Comments){ <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//如果是评论则只显示评论视图</span>
        imageView.hidden = <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">true</span>
    }<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">else</span>{ <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//否则显示图片</span>
        commentsView.hidden = <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">true</span>
    }
}
<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">override</span> func endPeek() {
    <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span>(peekType == .Comments){
        imageView.hidden = <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">false</span>
    }<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">else</span>{
        commentsView.hidden = <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">false</span>
    }
}</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li><li style="box-sizing: border-box; padding: 0px 5px;">10</li><li style="box-sizing: border-box; padding: 0px 5px;">11</li><li style="box-sizing: border-box; padding: 0px 5px;">12</li><li style="box-sizing: border-box; padding: 0px 5px;">13</li><li style="box-sizing: border-box; padding: 0px 5px;">14</li><li style="box-sizing: border-box; padding: 0px 5px;">15</li></ul>

Note

  • 如果要改变Peek窗口的size可以设置目标VC的preferredContentSize
  • 对于直接使用registerForPreviewingWithDelegate注册VC的self.view,虽然可以自动注册subviews,但是如果说你的VC中不止一种视图要触发Peek,那么它会分分钟教你做人的道理。

UITouch

高级玩法,绘图、游戏,把3D Touch发挥到极致。不过我也唔知玩也暂时没这方面需求,有需求看官方绘图demo

参考

Adopting 3D Touch on iPhone

ApplicationShortcuts Demo

ViewControllerPreviews Demo


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值