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

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

2015年,蘋果發(fā)布了iOS9以及iphone6s/iphone6s Plus,其中最具有創(chuàng)新的就是新的觸控方式3D Touch,相對于多點觸摸在平面二維空間的操作,3D Touch技術增加了對力度和手指面積的感知,可以通過長按快速預覽、查看你想要的短信、圖片或者超鏈接等內容,Peek和Pop手勢的響應時間可迅捷到 10ms和15ms等。

  • 用戶現(xiàn)在可以按主屏幕圖標立即訪問應用程序提供的功能。
  • 在您的應用程序中,用戶現(xiàn)在可以按視圖來查看其他內容的預覽,并獲得對功能的加速訪問
  • 在日常開發(fā)中,我們經常需要使用3D Touch中的兩個功能
    • 在主屏幕上對應用圖標使用3DTouch操作
    • 在應用程序內對某一控件使用3DTouch操作
  • 功能需要iOS9以上系統(tǒng)和iphone6s/iphone6s Plus及以上機型(模擬機現(xiàn)在也是可以的)
  • demo地址

一. 效果演練

1. 主屏幕快速操作

  • 通過按下iPhone 6s或iPhone 6s Plus上的應用程序圖標,用戶可以獲得一組快速操作。
  • 當用戶選擇快速操作時,您的應用程序激活或啟動,并跳轉到相應界面
    [圖片上傳失敗...(image-6546ef-1566389718417)]

2. Peek and Pop

  • 對界面內某一控件的3DTouch操作
  • Peek和Pop是應用內的一種全新交互模式,當用戶不斷增加力量在控件上按壓,會依次進入四個階段
  • 輕按控件,除觸發(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是應用內的一種全新交互模式,當用戶不斷增加力量在控件上按壓,會依次進入四個階段
  • 這里小編將通過ViewController里面的UITableViewCell進行延時功能

注意: 在動態(tài)添加快捷可選項前,需要用判斷是否支持3D Touch功能,以免在不支持的設備上運行程序導致閃退

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)會回調如下方法

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)行用力按壓進來的"
    
    //調整不被虛化的范圍,按壓的那個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)會回調如下方法

  • 用力按壓進入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預覽上向上滑動時顯示的快速操作
  • 在將要彈出的頁面內重寫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官方文檔


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

微信公眾號
最后編輯于
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
【社區(qū)內容提示】社區(qū)部分內容疑似由AI輔助生成,瀏覽時請結合常識與多方信息審慎甄別。
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發(fā)布,文章內容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關閱讀更多精彩內容

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

友情鏈接更多精彩內容