Demo同步更新到Swift2.3
本文出自: http://mokai.me/3d-touch.html
3D Touch最先應(yīng)用在Apple Watch上面瘫想,但叫Force Touch
徽诲,后在iPhone6s上加入了此特性霸奕,并改名3D Touch蒲障。值得注意的是目前3D Touch只支持iPhone6S以后的機(jī)型帽氓,包括現(xiàn)有Xcode7中6s的模擬器也不支持驼鹅,不過Github上的SBShortcutMenuSimulator項(xiàng)目通過Hack方式已經(jīng)實(shí)現(xiàn)了Quick Actions
快捷訪問州藕,但不能使用Peek&Pop
快速預(yù)覽榨馁。
如果你還不知道3D Touch是什么憨栽,可以看看官方宣傳視頻
環(huán)境
系統(tǒng)環(huán)境: iOS9 or later
開發(fā)環(huán)境: Swift2.3 & Xcode7.3.1
Demo: 3DTouchDemo
效果:
開始
3D Touch可以分為三種:
- Quick Actions【可以理解PC桌面的快捷方式】
- Peek&Pop【應(yīng)用內(nèi)快速預(yù)覽內(nèi)容】
- UITouch【自定義3D Touch事件】
Quick Actions 快捷方式
配置Actions可以通過工程Info.plist
文件靜態(tài)配置,也可以在運(yùn)行時(shí)動(dòng)態(tài)添加翼虫,兩者可以一起使用屑柔。
靜態(tài)配置在Info.plist
中UIApplicationShortcutItems
節(jié)點(diǎn)數(shù)組下添加相應(yīng)Actions Item信息
<key>UIApplicationShortcutItems</key>
<array>
<dict>
<key>UIApplicationShortcutItemIconType</key>
<string>UIApplicationShortcutIconTypeSearch</string>
<key>UIApplicationShortcutItemTitle</key>
<string>搜索</string>
<key>UIApplicationShortcutItemType</key>
<string>me.mokai.TouchDemo.action.search</string>
</dict>
...
</array>
動(dòng)態(tài)配置通過UIApplication的shortcutItems
添加,shortcutItems是一個(gè)UIApplicationShortcutItem
數(shù)組
let type = "me.mokai.TouchDemo.action.identify"
let title = "聽歌識(shí)別"
let shortcutItem = UIApplicationShortcutItem(type: type, localizedTitle: title,
localizedSubtitle: nil, icon: UIApplicationShortcutIcon(templateImageName: "quick_filter"), userInfo: nil)
application.shortcutItems = [shortcutItem]
<b>Note</b>
- Actions的圖標(biāo)可以使用系統(tǒng)預(yù)定的也可以自定義圖片
- 對(duì)于每個(gè)Actions來說
type
是必須的珍剑,它代表著我們從桌面點(diǎn)擊Actions進(jìn)入到應(yīng)用調(diào)用application(application, performActionForShortcutItem:, completionHandler:)
時(shí)的唯一標(biāo)識(shí)掸宛,另外userInfo可以附加每個(gè)actions的數(shù)據(jù),如最近聽歌的歌曲id - 當(dāng)APP啟動(dòng)時(shí)次慢,shortcutItems的值是上次動(dòng)態(tài)添加的旁涤,如果是第一次啟動(dòng)則為空數(shù)組。
- Actions最多顯示4個(gè)迫像,優(yōu)先顯示靜態(tài)Actions劈愚,然后剩余個(gè)數(shù)顯示shortcutItems的前幾個(gè)。
Peek&POP 快速預(yù)覽
好了闻妓,下面介紹本文重頭戲菌羽,先上效果
Peek窗口的內(nèi)容其實(shí)是目標(biāo)VC【ps即將要顯示的ViewController】的一個(gè)實(shí)時(shí)快照,但它不可以點(diǎn)擊由缆。Peek觸發(fā)階段有三種:
- 長按【顯示一個(gè)焦點(diǎn)視圖注祖,觸發(fā)Peek的源視圖高亮,其它視圖都處于模糊狀態(tài)】
- 輕壓【顯示Peek窗口均唉,此時(shí)如果Peek窗口支持Quick Actions是晨,往上滑會(huì)顯示Quick Actions菜單,此時(shí)的Peek窗口是不可以點(diǎn)擊的】
- 重壓 【進(jìn)入到真正的ViewController】
Peek由一個(gè)可響應(yīng)事件的View
觸發(fā)舔箭,默認(rèn)是關(guān)閉的罩缴,我們需要通過控制器的registerForPreviewingWithDelegate: sourceView:
方法注冊(cè)蚊逢,第一個(gè)參數(shù)為UIViewControllerPreviewingDelegate
的代理,Peek觸發(fā)輕壓時(shí)會(huì)調(diào)用其previewingContext:viewControllerForLocation
方法箫章,重壓時(shí)會(huì)調(diào)用previewingContext:commitViewController:
方法烙荷。第二個(gè)參數(shù)為觸發(fā)Peek事件的源視圖
//注冊(cè)
registerForPreviewingWithDelegate(self, sourceView: userVCBtn)
//Delegate
//輕壓,進(jìn)入第二階段檬寂,顯示Peek窗口
func previewingContext(previewingContext: UIViewControllerPreviewing, viewControllerForLocation location: CGPoint) -> UIViewController? {
let userVc = self.storyboard?.instantiateViewControllerWithIdentifier("UserViewController") as! UserViewController
return userVc;
}
//重壓终抽,進(jìn)入第三階段,顯示真正的ViewController
func previewingContext(previewingContext: UIViewControllerPreviewing, commitViewController viewControllerToCommit: UIViewController) {
showViewController(viewControllerToCommit, sender: self)
}
如果Peek窗口需要Quick Actions菜單桶至,在目標(biāo)VC中重寫previewActionItems
方法返回一個(gè)UIPreviewActionItem
或者一個(gè)UIPreviewActionGroup
數(shù)組就行了昼伴。
//目標(biāo)VC
lazy var previewActions: [UIPreviewActionItem] = {
func previewActionForTitle(title: String, style: UIPreviewActionStyle = .Default) -> UIPreviewAction {
return UIPreviewAction(title: title, style: style) { previewAction, viewController in
print("點(diǎn)擊了\(title)") //這里是Actions響應(yīng)
}
}
let action1 = previewActionForTitle("關(guān)注TA",style: .Destructive) //顯示紅色,代表重要Action
let action2 = previewActionForTitle("私信TA")
//子Actioons
let subAction1 = previewActionForTitle("微博")
let subAction2 = previewActionForTitle("好友圈")
let subAction3 = previewActionForTitle("QQ")
let subAction4 = previewActionForTitle("微信")
let groupedActions = UIPreviewActionGroup(title: "分享…", style: .Default, actions: [subAction1, subAction2, subAction3, subAction4] )
return [action1, action2, groupedActions]
}()
override func previewActionItems() -> [UIPreviewActionItem] {
return previewActions
}
更快速的方法
上面是代碼激活Peek的方式塞茅,還有更Peek的方式:直接在Storyboard中使用Segue亩码,在Segue屬性面板中把Peek & Pop 勾選上就完事了。
使用這種方式指定我們?cè)诖a中連注冊(cè)都不用野瘦,所以使用SB的項(xiàng)目適配3D Touch那是分分鐘搞定的事描沟,尤其在Xcode7出了Storyboard References
后,我大 Swift + Storyboard
組合勢(shì)必統(tǒng)一iOS界~
好了鞭光,有點(diǎn)小激動(dòng)了吏廉,繼續(xù)回到正文
在正常情況下,Peek窗口默認(rèn)顯示目標(biāo)VC的整個(gè)View惰许,但在實(shí)際應(yīng)用中席覆,可能會(huì)有更多的需求,比如說二個(gè)Button Push的是同一個(gè)VC汹买,但是需要分別顯示不同的Peek窗口佩伤。
其實(shí)也很簡單,我們只需要自定義一個(gè)Peek的生命周期擴(kuò)展就行了晦毙,previewingContext:viewControllerForLocation:
方法中代表Peek的開始生巡,previewingContext:commitViewController
代表Peek的結(jié)束,然后在目標(biāo)VC中重寫二個(gè)方法就行了
//UIViewController+PeekCycle.swift
/**
Peek生命周期
**/
extension UIViewController {
//開始peek见妒,VC為Peek顯示做初始化
func beginPeek(){}
//結(jié)束peek,VC為真正顯示做初始化
func endPeek(){}
}
//Delegate
func previewingContext(previewingContext: UIViewControllerPreviewing, viewControllerForLocation location: CGPoint) -> UIViewController? {
let detailVc = self.storyboard?.instantiateViewControllerWithIdentifier("DetailViewController") as! DetailViewController
//指定Peek窗口類型
detailVc.peekType = .Image
//設(shè)置Peek的高度
detailVc.preferredContentSize = CGSize(width: 0.0, height: 320);
detailVc.view //先訪問一下view孤荣,初始化
detailVc.beginPeek() //peek開始
return detailVc;
}
func previewingContext(previewingContext: UIViewControllerPreviewing, commitViewController viewControllerToCommit: UIViewController) {
viewControllerToCommit.endPeek() //peek結(jié)束
showViewController(viewControllerToCommit, sender: self)
}
//目標(biāo)VC
override func beginPeek() {
if(peekType == .Comments){ //如果是評(píng)論則只顯示評(píng)論視圖
imageView.hidden = true
}else{ //否則顯示圖片
commentsView.hidden = true
}
}
override func endPeek() {
if(peekType == .Comments){
imageView.hidden = false
}else{
commentsView.hidden = false
}
}
<b>Note</b>
- 如果要改變Peek窗口的size可以設(shè)置目標(biāo)VC的
preferredContentSize
- 對(duì)于直接使用
registerForPreviewingWithDelegate
注冊(cè)VC的self.view,雖然可以自動(dòng)注冊(cè)subviews须揣,但是如果說你的VC中不止一種視圖要觸發(fā)Peek盐股,那么它會(huì)分分鐘教你做人的道理。
UITouch
高級(jí)玩法耻卡,繪圖疯汁、游戲,把3D Touch發(fā)揮到極致卵酪。不過我也唔知玩也暫時(shí)沒這方面需求涛目,有需求看官方繪圖demo
參考
Adopting 3D Touch on iPhone
ApplicationShortcuts Demo
ViewControllerPreviews Demo
小小廣告
本人目前是一名自由職業(yè)者秸谢,接受移動(dòng)兩端的項(xiàng)目開發(fā),如果你有需求或者有資源請(qǐng)速與我聯(lián)系吧霹肝,QQ865425695