3D Touch介绍:电子秤App与快捷操作
?
隨著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元素(UILabel和UIImage),并關聯了ViewController.swift。
這個App的設計很簡單:ViewController上有兩個Label:一個標題和一個顯示按壓百分比的文本。
那…開始寫代碼吧!在iPhone6s和6s Plus上,UITouch對象多了兩個CGFloat類型的屬性,分別是force和maximumPossibleForce。force表示按得有多重,1.0表示常規狀態的值。maximumPossibleForce表示能承受的最大壓力值。
無論什么情況,當用戶觸摸屏幕時,touchesBegan方法會被調用,接著就是touchesMoved(如果用戶手指在屏幕上滑動,那么touchedCancelled與touchesEnded也會被調用)。在這個App中,我們只需要關注touchesMoved方法。touchesMoved有兩個參數:touches和event。touches是一個裝著UITouch對象的NSSet類型集合(集合無序,并且無重復)。我們必須要確保在touches中只有一個UITouch對象,但也有考慮不完全的時候,所以強烈建議大家先利用可選綁定來判斷touches.first(touches中的第一個UITouch對象)是否是空。在ViewController.swift中添加以下代碼:
override func touchesMoved(touches: Set, withEvent event: UIEvent?) { if let touch = touches.first { if在這個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如果你在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…
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 在工程中的路徑。最后一件事,就是實現用戶觸發快捷操作的處理流程??旖莘绞叫枰?strong>AppDelegate.swift的performActionForShortcutItem方法中處理。當使用快捷操作啟動時,這個方法會被調用。所以,實現這個方法,并在方法中處理快捷操作:
func application(application: UIApplication, performActionForShortcutItem shortcutItem: UIApplicationShortcutItem, completionHandler: (Bool) -> Void) {// Handle quick actionscompletionHandler(handleQuickAction(shortcutItem))}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 }
一切都是這么簡單?,F在把程序跑起來,使用快捷操作來啟動App,就可以看到背景已經是藍色了。
?
還有一件事
func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions:[NSObject: AnyObject]?) -> Bool {// Override point for customization after application launch.self.window?.backgroundColor = UIColor.whiteColor() return true }
問題來了:當使用快捷操作喚醒程序時,willFinish,didFinish和performActionForShortcutItem都會被調用。所以背景色會先設置成白色,接著又被設置成了藍色。顯然你不想在使用快捷操作啟動時,背景色被設置成白色。
要解決這個問題,我們需要在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
因為我們已經在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的應用了,如游戲和畫圖,還有一些我想象不到的應用。或許還可以看到計量重量的應用,比如稱一個水果的重量,或是一個放置在屏幕上的物體的重量等等 :>。
轉載于:https://www.cnblogs.com/yujidewu/p/5741139.html
總結
以上是生活随笔為你收集整理的3D Touch介绍:电子秤App与快捷操作的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 微分和积分公式大全
- 下一篇: 拯救者R9000p搜不到wifi 解决方