Swift開發(fā)之3DTouch實用演練
2015年,蘋果發(fā)布了iOS9以及
iphone6s/iphone6s Plus
旬蟋,其中最具有創(chuàng)新的就是新的觸控方式3D Touch,相對于多點觸摸在平面二維空間的操作油昂,3D Touch技術增加了對力度和手指面積的感知,可以通過長按快速預覽、查看你想要的短信冕碟、圖片或者超鏈接等內(nèi)容拦惋,Peek和Pop手勢的響應時間可迅捷到 10ms和15ms等。
- 用戶現(xiàn)在可以按主屏幕圖標立即訪問應用程序提供的功能安寺。
- 在您的應用程序中厕妖,用戶現(xiàn)在可以按視圖來查看其他內(nèi)容的預覽,并獲得對功能的加速訪問
- 在日常開發(fā)中,我們經(jīng)常需要使用3D Touch中的兩個功能
- 在主屏幕上對應用圖標使用3DTouch操作
- 在應用程序內(nèi)對某一控件使用3DTouch操作
- 功能需要iOS9以上系統(tǒng)和
iphone6s/iphone6s Plus
及以上機型(模擬機現(xiàn)在也是可以的) - demo地址
一. 效果演練
1. 主屏幕快速操作
- 通過按下iPhone 6s或iPhone 6s Plus上的應用程序圖標挑庶,用戶可以獲得一組快速操作言秸。
- 當用戶選擇快速操作時,您的應用程序激活或啟動迎捺,并跳轉到相應界面
[圖片上傳失敗...(image-6546ef-1566389718417)]
2. Peek and Pop
- 對界面內(nèi)某一控件的3DTouch操作
- Peek和Pop是應用內(nèi)的一種全新交互模式,當用戶不斷增加力量在控件上按壓,會依次進入四個階段
- 輕按控件,除觸發(fā)Peek的控件外,其他區(qū)域全部虛化
- 繼續(xù)用力Peek被觸發(fā),展示Pop界面快照
- 向上滑動展示快捷選項
- 繼續(xù)用力跳轉進入Pop界面
[圖片上傳失敗...(image-50a84b-1566389718417)]
[圖片上傳失敗...(image-9fc94-1566389718417)]
[圖片上傳失敗...(image-f8f90b-1566389718417)]
3. 注意
- 3D Touch僅在3D Touch設備上可用举畸,如果啟用。在iOS 9以上凳枝,默認情況下啟用3D Touch抄沮。
- 用戶可以在設置>常規(guī)>輔助功能> 3D觸摸中關閉3D觸摸。
- 當3D Touch可用時岖瑰,利用其功能合是。當它不可用時,提供替代方法锭环,例如通過使用觸摸和保持聪全。
- 3D Touch功能支持VoiceOver。
二. 主屏幕操作
-
ShortcutItem
功能允許用戶在主屏幕上對應用圖標使用3DTouch
操作,如果本次操作有效,則會給出幾個快捷可選項允許用戶進行操作 - 主屏幕icon上的快捷標簽的實現(xiàn)方式有兩種辅辩,一種是在工程文件info.plist里靜態(tài)設置难礼,另一種是代碼的動態(tài)實現(xiàn)
- 優(yōu)先顯示靜態(tài)添加,總數(shù)達到4個不再顯示
1. 靜態(tài)設置
- 在info.plist中添加
UIApplicationShortcutItems
關鍵字,以如下方式配置即可
其中各個關鍵字釋義如下:
-
UIApplicationShortcutItemType
: 快捷可選項的特定字符串(必填) -
UIApplicationShortcutItemTitle
: 快捷可選項的標題(必填) -
UIApplicationShortcutItemSubtitle
: 快捷可選項的子標題(可選) -
UIApplicationShortcutItemIconType
: 快捷可選項的圖標(可選) -
UIApplicationShortcutItemIconFile
: 快捷可選項的自定義圖標(可選) -
UIApplicationShortcutItemUserInfo
: 快捷可選項的附加信息(可選)
2. 動態(tài)添加UIApplicationShortcutItem
2-1. UIApplicationShortcutItem
初始化方法
UIApplicationShortcutItem(type: String, localizedTitle: String, localizedSubtitle: String?, icon: UIApplicationShortcutIcon?, userInfo: [AnyHashable : Any]?)
- 參數(shù)介紹
-
type
: 快捷可選項的特定字符串(必填) -
localizedTitle
: 快捷可選項的標題(必填) -
localizedSubtitle
: 快捷可選項的子標題(可選) -
icon
: 快捷可選項的圖標(可選) -
userInfo
: 快捷可選項的附加信息(可選)
-
2-1. 圖標
2-1-1. 初始化方式
//方式一: 自定義圖標
//注: 自定義圖標需要使用鏤空圖標,同時建議1倍圖標大小為35*35
UIApplicationShortcutIcon(templateImageName: String)
//方式二: 使用系統(tǒng)圖標
UIApplicationShortcutIcon(type: UIApplicationShortcutIconType)
2-1-2. 系統(tǒng)圖標樣式如下
2-3. 具體實現(xiàn)代碼如下
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
//3D Touch
let homeIcon = UIApplicationShortcutIcon(type: .compose)
let homeItem = UIApplicationShortcutItem(type: "homeAnchor", localizedTitle: "首頁", localizedSubtitle: "點擊進入首頁", icon: homeIcon, userInfo: nil)
let playIcon = UIApplicationShortcutIcon(type: .play)
let playItem = UIApplicationShortcutItem(type: "play", localizedTitle: "播放", localizedSubtitle: "", icon: playIcon, userInfo: nil)
let userIcon = UIApplicationShortcutIcon(type: .search)
let userItem = UIApplicationShortcutItem(type: "username", localizedTitle: "用戶名", localizedSubtitle: "", icon: userIcon, userInfo: nil)
UIApplication.shared.shortcutItems = [homeItem, playItem, userItem]
return true
}
2-4. item點擊跳轉
- 可根據(jù)
type
標識判斷 - 可根據(jù)
localizedTitle
標識判斷
//菜單跳轉
func application(_ application: UIApplication, performActionFor shortcutItem: UIApplicationShortcutItem, completionHandler: @escaping (Bool) -> Void) {
guard let tabBarVC = window?.rootViewController as? MainViewController else { return }
//根據(jù)type唯一標識進行判斷跳轉, 或者根據(jù)localizedTitle判斷
switch shortcutItem.type {
case "homeAnchor":
tabBarVC.selectedIndex = 1
case "play":
let username = ShowRoomViewController()
username.hidesBottomBarWhenPushed = true
tabBarVC.selectedViewController?.childViewControllers.first?.present(username, animated: true, completion: nil)
case "username":
let username = NameViewController()
username.hidesBottomBarWhenPushed = true
tabBarVC.selectedViewController?.childViewControllers.last?.navigationController?.pushViewController(username, animated: true)
default:
tabBarVC.selectedIndex = 0
}
}
三. Peek and Pop
- Peek和Pop是應用內(nèi)的一種全新交互模式,當用戶不斷增加力量在控件上按壓,會依次進入四個階段
- 這里小編將通過ViewController里面的UITableViewCell進行延時功能
注意: 在動態(tài)添加快捷可選項前,需要用判斷是否支持3D Touch功能,以免在不支持的設備上運行程序?qū)е麻W退
1. 判斷是否支持3D Touch功能
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
var cell = tableView.dequeueReusableCell(withIdentifier: "cell")
let model = happyVM.anchorGroups[indexPath.section].anchors[indexPath.row]
if cell == nil {
cell = UITableViewCell(style: .default, reuseIdentifier: "cell")
cell?.textLabel?.text = model.room_name
cell?.accessoryType = .disclosureIndicator
}
---
//這里是添加判斷是否支持3D Touch的代碼
if #available(iOS 9.0, *) {
if traitCollection.forceTouchCapability == .available {
//支持3D Touch
//注冊Peek & Pop功能
registerForPreviewing(with: self, sourceView: cell!)
}
}
---
return cell!
}
檢測是否支持3D Touch:UIForceTouchCapability是一個枚舉值,取值如下:
case unknown //3D Touch檢測失敗
case unavailable //3D Touch不可用
case available //3D Touch可用
2. 給對應view注冊3Dtouch事件
- 在判斷支持3Dtouch里面注冊
//注冊Peek & Pop功能
self.registerForPreviewing(with: self, sourceView: cell!)
3. 遵守UIViewControllerPreviewingDelegate
協(xié)議
- 需要實現(xiàn)Peek & Pop交互的控件所在的控制器遵循協(xié)議并實現(xiàn)兩個代理方法
3-1. 當進入Peek狀態(tài)時,系統(tǒng)會回調(diào)如下方法
func previewingContext(_ previewingContext: UIViewControllerPreviewing, viewControllerForLocation location: CGPoint) -> UIViewController? {
//1. 獲取按壓的cell所在的行
guard let cell = previewingContext.sourceView as? UITableViewCell else { return UIViewController() }
let indexPath = tableVIew.indexPath(for: cell) ?? IndexPath(row: 0, section: 0)
//2. 設定預覽界面
let vc = ShowRoomViewController()
// 預覽區(qū)域大小(可不設置), 0為默認尺寸
vc.preferredContentSize = CGSize(width: 0, height: 0)
vc.showStr = "我是第\(indexPath.row)行用力按壓進來的"
//調(diào)整不被虛化的范圍玫锋,按壓的那個cell不被虛化(輕輕按壓時周邊會被虛化蛾茉,再少用力展示預覽,再加力跳頁至設定界面)
let rect = CGRect(x: 0, y: 0, width: kScreenWidth, height: 44)
//設置觸發(fā)操作的視圖的不被虛化的區(qū)域
previewingContext.sourceRect = rect
//返回預覽界面
return vc
}
3-2. 當進入Pop狀態(tài)時,系統(tǒng)會回調(diào)如下方法
- 用力按壓進入
viewControllerToCommit
func previewingContext(_ previewingContext: UIViewControllerPreviewing, commit viewControllerToCommit: UIViewController) {
viewControllerToCommit.hidesBottomBarWhenPushed = true
show(viewControllerToCommit, sender: self)
}
來看看效果
3-4. 當彈出預覽時撩鹿,上滑預覽視圖谦炬,出現(xiàn)預覽視圖中快捷選項
var previewActionItems: [UIPreviewActionItem] { get }
-
previewActionItems
用戶在3D Touch預覽上向上滑動時顯示的快速操作 - 在將要彈出的頁面內(nèi)重寫previewActionItems的get屬性
extension ShowRoomViewController {
//重寫previewActionItems的get方法
override var previewActionItems: [UIPreviewActionItem] {
let action1 = UIPreviewAction(title: "跳轉", style: .default) { (action, previewViewController) in
let showVC = ShowRoomViewController()
showVC.hidesBottomBarWhenPushed = true
previewViewController.navigationController?.pushViewController(showVC, animated: true)
}
let action3 = UIPreviewAction(title: "取消", style: .destructive) { (action, previewViewController) in
print("我是取消按鈕")
}
////該按鈕可以是一個組,點擊該組時节沦,跳到組里面的按鈕键思。
let subAction1 = UIPreviewAction(title: "測試1", style: .selected) { (action, previewViewController) in
print("我是測試按鈕1")
}
let subAction2 = UIPreviewAction(title: "測試2", style: .selected) { (action, previewViewController) in
print("我是測試按鈕2")
}
let subAction3 = UIPreviewAction(title: "測試3", style: .selected) { (action, previewViewController) in
print("我是測試按鈕3")
}
let groupAction = UIPreviewActionGroup(title: "更多", style: .default, actions: [subAction1, subAction2, subAction3])
return [action1, action3, groupAction]
}
}
action的各種樣式
public enum UIPreviewActionStyle : Int {
//默認樣式
case `default`
//右側有對勾的樣式
case selected
//紅色字體的樣式
case destructive
}
3-5. force
和 maximumPossibleForce
到此,3DTouch在APP中的集成就先介紹這些甫贯,3DTouch中還有個重要的屬性--壓力屬性(force 和 maximumPossibleForce)這里簡單介紹下
- 手指在屏幕上慢慢增加力度在減少力度吼鳞,可以看到view背景色的變化
- 程序運行后找到
我的
->頭像(用戶名)
查看效果 - 代碼找到
NameViewController.swift
查看
override func touchesMoved(_ touches: Set<UITouch>, with event: UIEvent?) {
let touch = touches.first ?? UITouch()
//獲取重按力度
print("平均觸摸的力--\(touch.force)")
print("觸摸的最大可能力--\(touch.maximumPossibleForce)")
let change = touch.force / touch.maximumPossibleForce
view.backgroundColor = UIColor(red: 0.5, green: 0.5, blue: change, alpha: 1)
}
此外還有以下屬性, 詳細可參考3D Touch官方文檔
var tapCount: Int
//手指觸摸此次觸摸的次數(shù)。
var timestamp: TimeInterval
//觸摸發(fā)生的時間或最后一次突變的時間叫搁。
var type: UITouchType
//觸摸的類型赔桌。
enum UITouchType
//接收的觸摸類型供炎。
var phase: UITouchPhase
//觸摸的階段。
enum UITouchPhase
//手指觸摸的階段疾党。
var maximumPossibleForce: CGFloat
//觸摸的最大可能力音诫。
var force: CGFloat
//觸摸力,其中值表示平均觸摸的力(由系統(tǒng)預定雪位,不是用戶特定的)竭钝。1.0
var altitudeAngle: CGFloat
//手寫筆的高度(弧度)。
func azimuthAngle(in: UIView?)
//返回觸控筆的方位角(弧度)茧泪。
func azimuthUnitVector(in: UIView?)
//返回指向觸控筆方位角方向的單位向量。
最后附上Demo地址
參考資料
歡迎您掃一掃下面的微信公眾號聋袋,訂閱我的博客队伟!