如下全部內容個人小站會同步更新!!!ios
iPhone X 剛出來的時候蘋果第一時間更新了新設備的交互文檔,其中針對了你們最關心的「系統手勢和App自帶手勢衝突」的問題也給出了相應的解決辦法:bash
雖然蘋果用黑體字寫着強烈不建議開發者干涉系統的手勢,可是爲了加強用戶體驗仍是開出了接口,蘋果管這個叫作 "edge protect" 由於進入App後系統手勢都是從邊緣觸發,引發衝突的地方也會是在邊緣中。app
根據官方文檔描述,在衝突區域第一次執行手勢的時候會優先觸發App的內部手勢,當短期內再次進行一樣的操做則會觸發系統手勢。也就是將系統手勢延遲到下一次執行。ide
根據官方文檔找到對應的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); 複製代碼
該方法是用來控制子試圖控制器是否容許開發者控制edge protect的開啓或是關閉。若是實現了這個方法而且返回值不爲空那麼子VC的edge protect設置就會遵循父VC的設置,跟隨父VC是否延遲執行系統手勢。ui
該方法是設置edge protect的方法,返回值是一個邊界的枚舉this
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手勢一直有着最高的優先級。不過上下就很好理解,底部上拉出控制中心,頂部下拉是通知中心。spa
無限制code
當不作任何限制時候在頂部和底部很容易觸發到系統的手勢,他們會優先於Tab.eView的scroll手勢執行,雖然說屏幕大部分的界面仍是執行TableView手勢的,可是當用戶誤觸到邊界的時候仍是會稍稍影響體驗,尤爲是在全屏模式下、相機、視頻、遊戲等cdn
Edge Protent
在對應的ViewControll中添加以下代碼,咱們這邊開啓的是全部邊界限制其中包括了上、下邊界。在下拉或者上拉的話會先觸發App內部手勢,同時出現一個小箭頭而後在箭頭消失以前再次滑動就會觸發系統手勢。
-(UIRectEdge)preferredScreenEdgesDeferringSystemGestures
{
return UIRectEdgeAll;
}
複製代碼
這個方法是在應用內部動態控制edge protect,咱們能夠在上個方法中返回一個BOOL變量,而後根據須要改變該變量的值,而後調用該方法進行刷新。
iPhone X在系統手勢上面交互和其餘設備仍是有必定區別的,由於加入了Home Indicator的緣由,引入了新的手勢,同時對以往的手勢也作了相應的調整。
在iPhone X 中通知中心和控制中心所有都移動到了由頂部劉海處下拉和右上角下拉來觸發。本來底部的全部手勢都被Home Indicator佔用。其實Edge Protect在這裏依然適用,只是對於Home Indicator的手勢有一個小插曲。正常來講他在底部,就應該受到UIRectEdgeBottom 或者是 UIRectEdgeAll控制,可是一開始蘋果並無這麼作,不論怎麼寫代碼,他都有着最高的優先級,在iPhone X剛發佈我就試圖去處理交互問題,由於海報工廠並無傳統的UITabBarController,且裏面全部的tableView都是直通到底,可是始終都沒法延遲執行與Home Indicator相關的任何手勢。
後來看了其餘遊戲,視頻類App在iPhone X上的表現也都是如此。騰訊的王者榮耀,網易的吃雞都是同樣。騰訊官方給出的解釋是暫時開起引導式訪問,也仍然不方便。後來在今年1月25日蘋果推送了iOS 11.2.5的版本更新,而後王者榮耀也跟着進行了一波更新,在進入遊戲時候就會發現,底部的Home Indicator當你一段時間不去觸碰它的時候由黑色或者白色(根據當前的屏幕顯示的內容來決定)變成很是透明的灰色,當你第一次進行操做會默認執行App內手勢,同時激活Home Indicator,短期內進行第二次操做就能夠返回桌面
一開覺得是有新的API出現,不過看了交互文檔並無新的東西,並且小版本的系統更新應該也不會出現新的東西。因此找到了以前的edge protect 代碼運行後確實能夠達到效果。對於視頻,遊戲等App,確實能夠起到很好的防誤觸的效果。遺憾的是並無太多的人使用這個功能。目前主流的大型遊戲,包括Gameloft出品的遊戲都沒作相應的處理。
若是說上面的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的滑動並不能觸發顯示,不過只是是隱藏,可是手勢依然可使用。
若是是feed流界面搭配酷一點的UI就會提升沉浸感,好比這樣:
有的人可能會問若是說點擊的手勢會觸發它再次顯示那我獲取window上的交互每次在它即將顯示的時候經過setNeedsUpdateOfHomeIndicatorAutoHidden在讓他隱藏不就行了嗎?這樣一來既不影響系統手勢也不會讓它在顯示出來,其實我本身試過不行的,畢竟蘋果不會讓你這樣改。
須要注意的是:prefersHomeIndicatorAutoHidden和preferredScreenEdgesDeferringSystemGestures不可一塊兒使用,若是一塊兒使用的話後者是不生效的。