Instagram 的 3D Touch 經驗談

發表於2015-11-15

上週,Apple釋出了最新的iPhone產品線,從iPhone 6s開始,產品都新增了一項硬體屬性,叫做3D touch。作為螢幕的一部分,新的感測器將能識別用力按下螢幕的動作並檢測到精確的壓力變化。

同新的硬體一起,Apple釋出了3個新的API,幫助開發者為App新增另一維度的互動。”Quick Actions”讓你在點選app圖示時選擇四個選單項。另一個功能可以讓你“預覽”某項內容,然後展示內部更詳細的資訊。最後一個API通過UITouch物件提供給開發者按壓動作的詳情,比如力度和maximumPossibleForce。

我們有機會在這項新功能釋出之初就整合它到Instagram中。在新增了shortcuts和peeking功能後,照片和視訊看起來是如此自然,這很讓人驚喜。這些新的API在新增3D互動功能時銜接自然,我們整理了實施時的一些要點。

快捷操作(Quick Actions)

快捷操作讓使用者可以快速跳轉到app的某項功能中,而忽略掉中間步驟。例如在Instagram中,我們新增最常用的幾項功能到快捷操作中:Search, Direct, Activity和Creation.

在主介面新增快捷操作相當簡單,只需要建立UIApplicationShortcutItems的陣列,並新增到app的delegate中。每個item都有一個代表型別的字串和可選的UIApplicationShortcutIcon作為icon。

在Instagram中,我們建立了UIApplicationShortcutItem的擴充套件,用來建立快捷方式。

根據使用者是否登入的條件,我們動態的配置快捷方式的item:

我們的架構已經處理過諸如app連結和推送通知的流程,因此只需要在-application:performActionForShortcutItem:completionHandler:方法中呼叫對應的流程即可。

Peek and Pop(預覽和詳閱)

如同使用放大鏡拉近視角,預覽(Peek)內容(照片、視訊)讓你可以獲得更多資訊而不需要載入完整內容。

Instagram首先將Peek功能新增到了小圖片和視訊上。

Peek(預覽)和Pop(詳閱)相關的API為UIViewControllerPreviewingDelegate,它通過view來註冊。在Instagram中,我們只將其註冊到可以接受到touch事件的controller的view上。當3D touch事件發生時,delegate來檢測view中的哪個物件被點選。

如果delegate判斷有Peek(預覽)動作發生,它仍需要處理兩件事情:1. 設定預覽動作發生的view的rect;2. 返回展示的viewcontroller。

當3D touch發生時,會傳遞給你context資訊,包含源view和點選發生的point。自定義的delegate需要通過這個point對映到一個view,然後查詢到需要預覽的資料。

大多數的Instagram功能基於UICollectionView和UITableView實現。這兩者在資料和UI間對應方面都有不錯的API支援。

將預覽相關的API和現有的view和功能結合後,檢視Instagram照片和視訊變的異常簡單。

我們為header和comment中的使用者名稱新增了檢視資訊的功能。用來預覽使用者資訊的delegate和顯示照片/視訊的實現類似:

  • 使用3D touch點選的location和查詢到的index path找到對應的cell。
  • 將點選的point關聯轉換到cell中的textview上。
  • 通過該point獲取到text view中的attributed string的屬性。
  • 如果找到了使用者名稱稱的屬性,則返回IGUserPreviewController。

將這些實現串起來,看起來就像這樣:

混合內容展示

Instagram中的activity feed功能包含了使用者的tag和縮圖。我們之前分別建立過UIViewControllerPreviewingDelegate的物件,用來顯示這兩種內容。這裡我們需要把這些組合在一起。

拷貝已有程式碼到新的delegate中的做法並不明智。我們選擇使用composition模式來組合profile和post展示的delegate程式碼,這樣建立一個新的物件,只需要傳遞touch 事件即可。

預覽檢視控制器

用來顯示預覽的controller只是UIViewController的子類,在某些特別屬性上有所不同。

一開始,controller完全無法互動,你無法在上面點選按鈕或新增自定義手勢。這裡我們需要提供遵循UIPreviewActionItem協議的物件組成的陣列。在Instagram中,我們只用UIPreviewActions。

這些功能看起來很像UIAlertController的action item。

在整個Instagram程式中,我們只在需要的時候載入資料,並快取以備以後使用。這樣做既節省了網路等待的時間,又不會浪費使用者的頻寬。

有時,當預覽使用者profile時,我們獲取的資料還不足以用來顯示最新照片或關注者數量。預覽用的view controller仍然會呼叫viewDidLoad, viewWillAppear:和其他UIViewController事件。在其中可以獲取網路資料並更新UI。

最後,我們發現可以通過修改controller的preferredContentSize來調整預覽檢視的大小,即便是controller已經展示了,這樣的改變仍可生效。不過,這個屬性無法作用於動畫中。

結論

對於Instagram來說,3D touch是2015年版本的“右鍵點選”。它新增了另一種深度,帶來了不同的互動意向:你可能還沒有決定跳轉到某個內容上去,但你肯定會對它感興趣。只要有這種想法,預覽內容的功能可以讓你對眼前內容快速一瞥,而不跳轉頁面,這樣可以快速返回到之前瀏覽的內容中。

快捷操作讓你能夠直接跳轉到建立新帖子的步驟中,也可以讓你快速檢視Instagram中最近發生了些什麼,而不需要啟動程式後,一步一步的點選。在“簡約”理念的指導下,快捷操作讓Instagram更好用。

相關文章