Swift開發(fā)之3DTouch實用演練

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關鍵字,以如下方式配置即可
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)圖標樣式如下
系統(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)
}

來看看效果

3D Touch1演示.gif

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. forcemaximumPossibleForce

到此,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地址


參考資料

iOS 3D touch開發(fā)

3D Touch官方文檔


歡迎您掃一掃下面的微信公眾號聋袋,訂閱我的博客队伟!

微信公眾號
最后編輯于
?著作權歸作者所有,轉載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市幽勒,隨后出現(xiàn)的幾起案子嗜侮,更是在濱河造成了極大的恐慌,老刑警劉巖啥容,帶你破解...
    沈念sama閱讀 211,194評論 6 490
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件锈颗,死亡現(xiàn)場離奇詭異,居然都是意外死亡咪惠,警方通過查閱死者的電腦和手機击吱,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,058評論 2 385
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來遥昧,“玉大人覆醇,你說我怎么就攤上這事√砍簦” “怎么了永脓?”我有些...
    開封第一講書人閱讀 156,780評論 0 346
  • 文/不壞的土叔 我叫張陵,是天一觀的道長鞋仍。 經(jīng)常有香客問我常摧,道長,這世上最難降的妖魔是什么威创? 我笑而不...
    開封第一講書人閱讀 56,388評論 1 283
  • 正文 為了忘掉前任落午,我火速辦了婚禮,結果婚禮上肚豺,老公的妹妹穿的比我還像新娘板甘。我一直安慰自己,他們只是感情好详炬,可當我...
    茶點故事閱讀 65,430評論 5 384
  • 文/花漫 我一把揭開白布盐类。 她就那樣靜靜地躺著寞奸,像睡著了一般。 火紅的嫁衣襯著肌膚如雪在跳。 梳的紋絲不亂的頭發(fā)上枪萄,一...
    開封第一講書人閱讀 49,764評論 1 290
  • 那天,我揣著相機與錄音猫妙,去河邊找鬼瓷翻。 笑死,一個胖子當著我的面吹牛割坠,可吹牛的內(nèi)容都是我干的齐帚。 我是一名探鬼主播,決...
    沈念sama閱讀 38,907評論 3 406
  • 文/蒼蘭香墨 我猛地睜開眼彼哼,長吁一口氣:“原來是場噩夢啊……” “哼对妄!你這毒婦竟也來了?” 一聲冷哼從身側響起敢朱,我...
    開封第一講書人閱讀 37,679評論 0 266
  • 序言:老撾萬榮一對情侶失蹤剪菱,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后拴签,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體孝常,經(jīng)...
    沈念sama閱讀 44,122評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,459評論 2 325
  • 正文 我和宋清朗相戀三年蚓哩,在試婚紗的時候發(fā)現(xiàn)自己被綠了构灸。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 38,605評論 1 340
  • 序言:一個原本活蹦亂跳的男人離奇死亡岸梨,死狀恐怖冻押,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情盛嘿,我是刑警寧澤洛巢,帶...
    沈念sama閱讀 34,270評論 4 329
  • 正文 年R本政府宣布,位于F島的核電站次兆,受9級特大地震影響稿茉,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜芥炭,卻給世界環(huán)境...
    茶點故事閱讀 39,867評論 3 312
  • 文/蒙蒙 一漓库、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧园蝠,春花似錦渺蒿、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,734評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽怠蹂。三九已至,卻和暖如春少态,著一層夾襖步出監(jiān)牢的瞬間城侧,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,961評論 1 265
  • 我被黑心中介騙來泰國打工彼妻, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留嫌佑,地道東北人。 一個月前我還...
    沈念sama閱讀 46,297評論 2 360
  • 正文 我出身青樓侨歉,卻偏偏與公主長得像屋摇,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子幽邓,可洞房花燭夜當晚...
    茶點故事閱讀 43,472評論 2 348

推薦閱讀更多精彩內(nèi)容

  • 概述 iOS10系統(tǒng)登錄中國,在系統(tǒng)中對3D Touch的使用需求更頻繁,所以對iOS9中便引入的3D Touch...
    微冷l閱讀 577評論 0 1
  • 前言 關于3D touch蘋果官方文檔是這么開始介紹的: 大意如下:iOS9開始炮温,所有新的手機都增加了一個三維的用...
    VV木公子閱讀 2,216評論 3 39
  • 發(fā)現(xiàn) 關注 消息 iOS 第三方庫、插件颊艳、知名博客總結 作者大灰狼的小綿羊哥哥關注 2017.06.26 09:4...
    肇東周閱讀 12,059評論 4 62
  • 定義常量# final String INFO ="Hello"全局常量public static final S...
    金琥閱讀 133評論 0 1
  • 今早情緒特別不好茅特,緊張心焦躁到不愿感受忘分,本來上廁所也上不出來了棋枕。站樁開始沒有前兩天一開始腿就抖。前半部分心一直是焦...
    張德芬幸福驛站咸陽閱讀 266評論 0 0