3D Touch介紹:電子秤App與快捷操作

來源:互聯網
上載者:User

標籤:

 

隨著iPhone6s與6s plus的到來,蘋果給我們展現了一種全新的互動方式:重按手勢。你可能知道,這個特性已經在Apple Watch和MacBook上推出了,不過那時叫Force Touch,就是字面上的意思,給使用者的互動添加一種新的維度。

如果你很好奇iPhone的Force Touch為啥要更名為3D Touch,那告訴你吧,you’re not alone(譯者註:請用MJ的調子唱出來…)。不久前,之前也對這名字糾結不已的Craig Federighi(譯者註:Apple進階副總裁)介紹了這個新特性,第一條微博就這樣產生了。也不知道Force Touch這名字有啥不好的,就因為有太多星球大戰的梗?(譯者註:其實我不知道這梗…)

但是,Force Touch和3d Touch確實不一樣!Force Touch只能識別重按。這方面3D Touch要靈敏多了,它能夠識別按壓的力度。

雖然說,這點不同看起來無足輕重,但是這使開發人員能開發更多精確計量方面的App。比如這一款名為Gravity的應用,它利用Force Touch讓你的iPhone成為了一個電子秤。雖然這款App被Apple拒了,但是這創意簡直太棒了。所以,為了展示3D Touch的工作流程,我們來做一個簡單的App。

先去下載這個初始案例。初始案例中只有一個空的Single View。我在裡面建立了App必要的UI元素(UILabelUIImage),並關聯了ViewController.swift

這個App的設計很簡單:ViewController上有兩個Label:一個標題和一個顯示按壓百分比的文本。

那…開始寫代碼吧!在iPhone6s和6s Plus上,UITouch對象多了兩個CGFloat類型的屬性,分別是forcemaximumPossibleForceforce表示按得有多重,1.0表示常規狀態的值。maximumPossibleForce表示能承受的最大壓力值。

無論什麼情況,當使用者觸控螢幕幕時,touchesBegan方法會被調用,接著就是touchesMoved(如果使用者手指在螢幕上滑動,那麼touchedCancelledtouchesEnded也會被調用)。在這個App中,我們只需要關注touchesMoved方法。touchesMoved有兩個參數:toucheseventtouches是一個裝著UITouch對象的NSSet類型集合(集合無序,並且無重複)。我們必須要確保在touches中只有一個UITouch對象,但也有考慮不完全的時候,所以強烈建議大家先利用可選綁定來判斷touches.firsttouches中的第一個UITouch對象)是否是空。在ViewController.swift中添加以下代碼:

override func touchesMoved(touches: Set, withEvent event: UIEvent?) {    if let touch = touches.first {        if #available(iOS 9.0, *) {            if traitCollection.forceTouchCapability == UIForceTouchCapability.Available {                // 3D Touch capable            }        }    }}

在這個if判斷中,還需要添加判斷當前裝置是否支援3D Touch的代碼。如果你只是做來玩,那就沒必要驗證。但是,如果是要上架的App,那就必須要判斷,畢竟像iPhone6這些舊裝置不支援3D Touch。

除此之外,我還使用了#available語句(Swift 2.0)對當前系統是否是iOS9+做了判斷。(如果你想學習更多Swift 2.0相關的知識,我就更加推薦你閱讀這篇文章了。)同樣,如果你的編譯環境是iOS9.0+,那麼這個判斷可以省略。

要得到按壓百分比?那太簡單了,只需要用force屬性除以maximumPossibleForce就可以了(例如:touch.maximumPossibleForce),maximumPossibleForce表示能承受的最大壓力值。然後,更新文本:

override func touchesMoved(touches: Set, withEvent event: UIEvent?) {    if let touch = touches.first {        if #available(iOS 9.0, *) {            if traitCollection.forceTouchCapability == UIForceTouchCapability.Available {                // 3D Touch capable                let force = touch.force/touch.maximumPossibleForce                forceLabel.text = "\(force)% force"            }        }    }}

如果你在iPhone6s/6s Plus上跑這個程式,按螢幕時就能看到壓力百分比了。但是,其實我們更想知道放在iPhone上物體的重量,而不是百分比。根據Ryan McLeod的App可以知道,感應器的計量範圍的最大值是385g。因此,maximumPossibleForce就相當於385g(相當於3.8N)。通過簡單的計算,就可以把壓力百分比轉為克。需要做的僅僅是用百分比*385。對於重於385g的物體,就把label改成類似於“385+ grams”這樣的文本好了。

到此,touchesMoved方法中的代碼更新為:

override func touchesMoved(touches: Set, withEvent event: UIEvent?) {            if let touch = touches.first {        if #available(iOS 9.0, *) {            if traitCollection.forceTouchCapability == UIForceTouchCapability.Available {                if touch.force >= touch.maximumPossibleForce {                    forceLabel.text = "385+ grams"                } else {                    let force = touch.force/touch.maximumPossibleForce                    let grams = force * 385                    let roundGrams = Int(grams)                    forceLabel.text = "\(roundGrams) grams"                }            }        }    }}

然後…你就有一個電子秤App…

還有一個小問題:當物體或者觸摸事件結束之後,文本沒有重設。你可以實現touchesEnded方法來達到效果:

override func touchesEnded(touches: Set, withEvent event: UIEvent?) {    forceLabel.text = "0 gram"}
主畫面上的快捷操作

另一個3D Touch的用法是主畫面上的快捷操作。快捷操作可以讓使用者從捷徑直接跳轉到App的某個地方。按壓App icon捷徑就會出現。在介紹3D Touch的時候,Twitter、Instagram等App就展示了這個新特性。

讓我們來給剛才的電子秤App添加一個快捷操作吧(把白色背景換成藍色)。要添加快捷操作,先開啟工程目錄中的info.plist(在導覽列上點擊工程名,在TARTGET中找到info選項卡)。在這個檔案中,添加UIApplicationShortcutItems數組。數組中的元素是包含一個快捷操作配置的字典:

  • UIApplicationShortcutItemType (必填):快捷操作的唯一標識符(String類型)。建議將bundle ID或者其他唯一字串作為標識符首碼。
  • UIApplicationShortcutItemTitle(必填):相當於快捷操作的title(String類型),使用者可以看到。例如“顯示最近一張照片”之類的文本。
  • UIApplicationShortcutItemSubtitle(可選):快捷操作的副標題(String類型)。例如“昨天拍攝的照片”。如果你想要給快捷操作添加一個icon,可以自訂,也可以使用系統內建的。
  • UIApplicationShortcutItemIconType(可選):表示你要選擇哪種系統表徵圖作為快捷操作的icon(String類型)。
  • UIApplicationShortcutItemIconFile(可選):表示給快捷操作添加自訂icon(String類型)。
  • UIApplicationShortcutItemUserInfo(可選):在快捷操作互動時傳遞的額外資訊(譯者註:類似於通知的UserInfo參數)(Dictionary 類型)。

在這個數組中,我們將會給自訂的快捷操作添加4個配置。然後,你的info.plist檔案看起來應該是這樣滴:

注意,我用到了$(PRODUCT_BUNDLE_IDENTIFIER)來代替com.appcoda.Scale(就是替代的 bundle ID)。這是出於安全考慮:無論在什麼情況下,如果我在General中修改了 bundle ID,那整個工程的 bundle ID 就都變了,這勢必會給項目帶來不曉得影響。這樣的話,我就需要手動去修改每個 bundle ID。在info.plist裡面可以看到,其實每個 Bundle Identifier 配置項都是用的$(PRODUCT_BUNDLE_IDENTIFIER)來表示 bundle ID 在工程中的路徑。

最後一件事,就是實現使用者觸發快捷操作的處理流程。捷徑需要在AppDelegate.swiftperformActionForShortcutItem方法中處理。當使用快捷操作啟動時,這個方法會被調用。所以,實現這個方法,並在方法中處理快捷操作:

func application(application: UIApplication, performActionForShortcutItem shortcutItem: UIApplicationShortcutItem, completionHandler: (Bool) -> Void) {    // Handle quick actions    completionHandler(handleQuickAction(shortcutItem))}

這個方法需要調用completionHandler,並傳入布爾值,這個布爾值取決於快捷操作成功與否。這裡我們封裝了一個handleQuickAction方法來處理捷徑。如果有多個快捷操作,最好的方式是使用枚舉,UIApplicationShortcutItemType作為枚舉的rawValue(譯者註:對枚舉不熟悉可以參考這篇文章)。定義一個枚舉,並實現handleQuickAction方法,在方法中修改背景色為藍色。

enum Shortcut: String {    case openBlue = "OpenBlue"}func handleQuickAction(shortcutItem: UIApplicationShortcutItem) -> Bool {    var quickActionHandled = false    let type = shortcutItem.type.componentsSeparatedByString(".").last!    if let shortcutType = Shortcut.init(rawValue: type) {        switch shortcutType {        case .openBlue:            self.window?.backgroundColor = UIColor(red: 151.0/255.0, green: 187.0/255.0, blue: 255.0/255.0, alpha: 1.0)            quickActionHandled = true        }    }    return quickActionHandled}

一切都是這麼簡單。現在把程式跑起來,使用快捷操作來啟動App,就可以看到背景已經是藍色了。

 

還有一件事

還有一個問題你別忘了…在程式啟動順序方面,啟動程式和使用快捷操作喚醒是有區別的。我們都知道,程式啟動會調用willFinishLaunchingWithOptionsdidFinishLaunchingWithOptions方法。但是當使用快捷操作喚醒時,只會觸發performActionForShortcutItem方法(譯者註:這就意味著,使用快捷操作來啟動會走三個方法,而使用快捷操作喚醒只會走一個,具體的方法列表如)。

如果你回頭看didFinishLaunchingWithOptions方法,會發現裡面我寫了一行設定背景色為白色的代碼。這個是在直接啟動程式時用的。

func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions:    [NSObject: AnyObject]?) -> Bool {    // Override point for customization after application launch.    self.window?.backgroundColor = UIColor.whiteColor()    return true}

問題來了:當使用快捷操作喚醒程式時,willFinishdidFinishperformActionForShortcutItem都會被調用。所以背景色會先設定成白色,接著又被設定成了藍色。顯然你不想在使用快捷操作啟動時,背景色被設定成白色。

要解決這個問題,我們需要在didFinishLaunchingWithOptions方法的實現中添加條件判斷:

func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions:    [NSObject: AnyObject]?) -> Bool {    print("didFinishLaunchingWithOptions called")    var isLaunchedFromQuickAction = false    // Check if it‘s launched from Quick Action    if let shortcutItem = launchOptions?[UIApplicationLaunchOptionsShortcutItemKey] as? UIApplicationShortcutItem {        isLaunchedFromQuickAction = true        // Handle the sortcutItem        handleQuickAction(shortcutItem)    } else {        self.window?.backgroundColor = UIColor.whiteColor()    }    // Return false if the app was launched from a shortcut, so performAction... will not be called.    return !isLaunchedFromQuickAction}

通過判斷可選值的UIApplicationLaunchOptionsShortcutItemKey得到使用者是否是通過快捷操作啟動。UIApplicationShortcutItem可以作為可選值的類型。如果程式是通過快捷操作啟動的,我們可以直接調用handleQuickAction方法將背景色改為藍色。

因為我們已經在didFinishLaunchingWithOption方法中調用了handleQuickAction,所以沒必要再在performActionForShortcutItem方法中調用一次。所以最後我們返回了一個false,告訴系統不要再去調用performActionForShortcutItem方法。

再次運行程式!完美!

最後

3D Touch是給程式添加另一種互動方式的好方法。但是你還是不要忘了,目前還不是所有裝置都支援3D Touch。

通過這篇文章,你應該能給你的App添加快捷操作,也能計量按壓力度了。

順便,你可以在這裡下載程式的最終版。同樣,歡迎大家留言。

 

 

 

【譯】3D Touch之我見

 

Hey,現在有了支援3D Touch的iPhone和iOS9,這是一項偉大的科技傑作。讓我們看看這為開發人員和使用者都帶來了什麼。文本主要是我對3D Touch的理解,然後列舉了一些需要注意的點。

出師不利

本來我想寫一篇關於3D Touch的導讀文章,但是遇到一個問題——Xcode7的模擬器並不能類比3D Touch。

蘋果官方的說法是:

Xcode7.0中,你必須使用支援3D Touch的真機進行開發。因為Xcode7.0的模擬器不支援3D Touch。

這是個悲傷的故事,但是又有什麼辦法呢。我想,蘋果應該會想辦法類比出來。可能在下一個Xcode發布版本中就能看到。

另一個問題則是新的iPhone還沒有在波蘭發售,可能還要等2周(譯者註:作者寫文在波蘭iPhone發售以前)。

還有一個辦法,我10月要在San Francisco和Palo Alto呆上整整一月,所以我可能會買一部iPhone,但不確定是6s還是6s plus。

如果買了裝置,那肯定會發布一大波3D Touch的文章。

Peek and pop操作

這是蘋果介紹3D Touch的第一個特性——或者說是兩個特性。

  • 輕壓(peek,輕度按壓)操作能讓使用者在不離開當前介面的情況下預覽內容。如果輕按某個選項能夠彈出一個小的矩形視圖,則表明它支援輕壓操作。
  • peek手勢彈出的視圖應該足夠大,這樣內容就不會被手指擋住,從而使用者可以選擇是否重壓,即pop操作(譯者註:peek操作即輕按,用於預覽,pop操作則是重壓,用於進一步確認。pop能滿足在預覽之後,進入特定頁面的需求)。
  • pop則是當使用者在peek彈出的視圖上加重按壓力度,顯示更詳細的內容。
  • 即使peek能給使用者足夠多的資訊,你也應該讓使用者將該操作轉化為pop。pop所顯示的介面應該和使用者點擊進入介面相同。
  • 請勿在peek預覽的介面中放入按鈕,因為使用者手指一離開預覽介面,預覽介面就會消失,所以根本點不到按鈕。
  • 當使用者在預覽介面中向上滑動時,peek可以提供一些快捷操作(quick action)。你可以在預覽介面中添加一些快捷操作,這樣使用者就可以上滑,然後選擇一個你所提供的操作了。
  • 如果你為某個選項提供了長按手勢事件(touch-and-hold,或者叫long press),那麼你可以用peek來代替長按手勢,這是一個很好的嘗試。
  • 如果你想使用快捷操作、peek和pop,那麼記住在使用前先判斷3D Touch是否可用。
  • 不是每個裝置都支援peek和pop操作的,並且3D Touch也可能處于禁用狀態。所以不要讓某些事件只能由peek來觸發。最好有一個備選方案,即視圖也能通過長按手勢來展示。
快捷操作

接下來,介紹一些使用者在重壓應用表徵圖時的一些快捷操作。

  • 彈出框包含了主標題、副標題與表徵圖。
  • 該操作可以在應用程式更新時,顯示更新資訊。
  • 你的應用在Home介面中,應該至少提供一個快捷選項。這樣使用者就可以使用手勢操作你的應用,方便快捷。
  • 醫用最多可以提供四個快捷操作。
  • 不要使用快捷操作來提醒使用者更新、變更之類的事。如有需要,通知(Notifications)更能勝任這些任務。
  • 快捷操作的命名應該簡潔,如有需要,還應該有副標題和表徵圖。盡量讓使用者明確該操作的作用。如果提供了副標題,那麼標題列將會更長,如果大小不能適應,系統會自動截取。如果沒有副標題,那麼主標題過長會自動換行。
最後

3D Touch是一個非常爽的特性,它提供了全新的互動方式。裝置中包含了一個線性震動器(Taptic Engine),所以按壓螢幕時,裝置能有一定響應——太好了,迫不及待想要試試。

非常遺憾,蘋果沒有在最新的Xcode 7 beta 2中解決無法類比的問題,還是希望他們儘快搞定吧——或許他們不修複是為了增加銷量,因為使用者已經迫不及待的想要試試這個新特性了,而最簡單粗暴的方式,就是買個新裝置 :D。

我已經迫不及待的想要嘗試基於3D Touch的應用了,如遊戲和畫圖,還有一些我想象不到的應用。或許還可以看到計量重量的應用,比如稱一個水果的重量,或是一個放置在螢幕上的物體的重量等等 :>。

3D Touch介紹:電子秤App與快捷操作

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.