關於iPhone X下Home鍵的隱藏和延遲響應

茉莉兒發表於2018-02-08

以下所有內容我的小站會同步更新!!!

iOS 11通用相關

Edge Protect

iPhone X 剛出來的時候蘋果第一時間更新了新裝置的互動文件,其中針對了大家最關心的“系統手勢和App自帶手勢衝突”的問題也給出了相應的解決辦法:

關於iPhone X下Home鍵的隱藏和延遲響應

雖然蘋果用黑體字寫著強烈不建議開發者干涉系統的手勢,但是為了增強使用者體驗還是開出了介面,蘋果管這個叫做 "edge protect" 因為進入App後系統手勢都是從邊緣觸發,引起衝突的地方也會是在邊緣中。

根據官方文件描述,在衝突區域第一次執行手勢的時候會優先觸發App的內部手勢,當短時間內再次進行同樣的操作則會觸發系統手勢。也就是將系統手勢延遲到下一次執行。

API Discussion

根據官方文件找到對應的API

// Override to return a child view controller or nil. If non-nil, that view controller's screen edges deferring system gestures will be used. If nil, self is used. Whenever the return value changes, -setNeedsScreenEdgesDeferringSystemGesturesUpdate should be called.
- (nullable UIViewController *)childViewControllerForScreenEdgesDeferringSystemGestures API_AVAILABLE(ios(11.0)) API_UNAVAILABLE(watchos, tvos);

// Controls the application's preferred screen edges deferring system gestures when this view controller is shown. Default is UIRectEdgeNone.
- (UIRectEdge)preferredScreenEdgesDeferringSystemGestures API_AVAILABLE(ios(11.0)) API_UNAVAILABLE(watchos, tvos);

// This should be called whenever the return values for the view controller's screen edges deferring system gestures have changed.
- (void)setNeedsUpdateOfScreenEdgesDeferringSystemGestures API_AVAILABLE(ios(11.0)) API_UNAVAILABLE(watchos, tvos);
複製程式碼

childViewControllerForScreenEdgesDeferringSystemGestures

該方法是用來控制子試圖控制器是否允許開發者控制edge protect的開啟或是關閉。如果實現了這個方法並且返回值不為空那麼子VC的edge protect設定就會遵循父VC的設定,跟隨父VC是否延遲執行系統手勢。

關於iPhone X下Home鍵的隱藏和延遲響應

preferredScreenEdgesDeferringSystemGestures

該方法是設定edge protect的方法,返回值是一個邊界的列舉

typedef NS_OPTIONS(NSUInteger, UIRectEdge) {
    UIRectEdgeNone   = 0,
    UIRectEdgeTop    = 1 << 0,
    UIRectEdgeLeft   = 1 << 1,
    UIRectEdgeBottom = 1 << 2,
    UIRectEdgeRight  = 1 << 3,
    UIRectEdgeAll    = UIRectEdgeTop | UIRectEdgeLeft | UIRectEdgeBottom | UIRectEdgeRight
} NS_ENUM_AVAILABLE_IOS(7_0);
複製程式碼

因為不論我們從shang、左、下、右邊都可觸發系統手勢,所以方法保護了四個邊框,將邊界觸發的手勢延遲執行,這個方法從iOS11開始使用,不過列舉中雖然有左右的邊界保護,但是系統手勢中還不清楚左右滑動會觸發什麼效果,實驗發現對於VC的左邊界右滑動pop手勢是無效的,也就是說這個pop手勢一直有著最高的優先順序。不過上下就很好理解,底部上拉出控制中心,頂部下拉是通知中心。

  • 無限制

    當不做任何限制時候在頂部和底部很容易觸發到系統的手勢,他們會優先於Tab.eView的scroll手勢執行,雖說螢幕大部分的介面還是執行TableView手勢的,但是當使用者誤觸到邊界的時候還是會稍稍影響體驗,尤其是在全屏模式下、相機、視訊、遊戲等

    關於iPhone X下Home鍵的隱藏和延遲響應

  • Edge Protent

    在對應的ViewControll中新增如下程式碼,我們這邊開啟的是所有邊界限制其中包括了上、下邊界。在下拉或者上拉的話會先觸發App內部手勢,同時出現一個小箭頭然後在箭頭消失之前再次滑動就會觸發系統手勢。

-(UIRectEdge)preferredScreenEdgesDeferringSystemGestures
{
    return UIRectEdgeAll;
}
複製程式碼

關於iPhone X下Home鍵的隱藏和延遲響應

setNeedsUpdateOfScreenEdgesDeferringSystemGestures

這個方法是在應用內部動態控制edge protect,我們可以在上個方法中返回一個BOOL變數,然後根據需要改變該變數的值,然後呼叫該方法進行重新整理。

關於iPhone X下Home鍵的隱藏和延遲響應

iPhone X使用相關

iPhone X在系統手勢上面互動和其他裝置還是有一定區別的,因為加入了Home Indicator的原因,引入了新的手勢,同時對以往的手勢也做了相應的調整。

iPhone X Edge Protect

在iPhone X 中通知中心和控制中心全部都移動到了由頂部劉海處下拉和右上角下拉來觸發。原本底部的所有手勢都被Home Indicator佔用。其實Edge Protect在這裡依然適用,只是對於Home Indicator的手勢有一個小插曲。正常來說他在底部,就應該受到UIRectEdgeBottom 或者是 UIRectEdgeAll控制,但是一開始蘋果並沒有這麼做,不論怎麼寫程式碼,他都有著最高的優先順序,在iPhone X剛釋出我就試圖去處理互動問題,因為海報工廠並沒有傳統的UITabBarController,且裡面所有的tableView都是直通到底,但是始終都無法延遲執行與Home Indicator相關的任何手勢。

關於iPhone X下Home鍵的隱藏和延遲響應

後來看了其他遊戲,視訊類App在iPhone X上的表現也都是如此。騰訊的王者榮耀,網易的吃雞都是一樣。騰訊官方給出的解釋是暫時開起引導式訪問,也仍然不方便。後來在今年1月25日蘋果推送了iOS 11.2.5的版本更新,然後王者榮耀也跟著進行了一波更新,在進入遊戲時候就會發現,底部的Home Indicator當你一段時間不去觸碰它的時候由黑色或者白色(根據當前的螢幕顯示的內容來決定)變成非常透明的灰色,當你第一次進行操作會預設執行App內手勢,同時啟用Home Indicator,短時間內進行第二次操作就可以返回桌面

關於iPhone X下Home鍵的隱藏和延遲響應

一開以為是有新的API出現,不過看了互動文件並沒有新的東西,而且小版本的系統更新應該也不會出現新的東西。所以找到了之前的edge protect 程式碼執行後確實可以達到效果。對於視訊,遊戲等App,確實可以起到很好的防誤觸的效果。遺憾的是並沒有太多的人使用這個功能。目前主流的大型遊戲,包括Gameloft出品的遊戲都沒做相應的處理。

關於iPhone X下Home鍵的隱藏和延遲響應

iPhone X Home Indicator Hidden

如果說上面的Edge Protect適合在遊戲中使用,那麼Home Indicator Hidden則更適合在非遊戲環境下增強App的沉浸感,尤其是全屏視屏播放、錄製的時候。同樣三個API,和Edge protect的用法完全一樣。

// Override to return a child view controller or nil. If non-nil, that view controller's home indicator auto-hiding will be used. If nil, self is used. Whenever the return value changes, -setNeedsHomeIndicatorAutoHiddenUpdate should be called.
- (nullable UIViewController *)childViewControllerForHomeIndicatorAutoHidden API_AVAILABLE(ios(11.0)) API_UNAVAILABLE(watchos, tvos);

// Controls the application's preferred home indicator auto-hiding when this view controller is shown.
- (BOOL)prefersHomeIndicatorAutoHidden API_AVAILABLE(ios(11.0)) API_UNAVAILABLE(watchos, tvos);

// This should be called whenever the return values for the view controller's home indicator auto-hiding have changed.
- (void)setNeedsUpdateOfHomeIndicatorAutoHidden API_AVAILABLE(ios(11.0)) API_UNAVAILABLE(watchos, tvos);
複製程式碼

上面寫的是自動隱藏,也就是說系統會根據當時的使用情況來進行顯示或者隱藏,而不是永久的隱藏掉,實際測試發當介面兩秒內沒有進行任何互動操作的時候Home Indicator會逐漸隱去,直達螢幕上出現了點選的操作,注意是點選,TableView的滑動並不能觸發顯示,不過只是是隱藏,但是手勢依然可以使用。

關於iPhone X下Home鍵的隱藏和延遲響應

如果是feed流介面搭配酷一點的UI就會提高沉浸感,比如這樣:

關於iPhone X下Home鍵的隱藏和延遲響應

有的人可能會問如果說點選的手勢會觸發它再次顯示那我獲取window上的互動每次在它即將顯示的時候通過setNeedsUpdateOfHomeIndicatorAutoHidden在讓他隱藏不就好了嗎?這樣一來既不影響系統手勢也不會讓它在顯示出來,其實我自己試過不行的,畢竟蘋果不會讓你這樣改。

坑點

需要注意的是:prefersHomeIndicatorAutoHidden和preferredScreenEdgesDeferringSystemGestures不可一起使用,如果一起使用的話後者是不生效的。

相關文章