不知道為什么圖片總是上傳失敗 如果有需要去我的小站看吧!!!!!簡書最近有點抽風啊
iOS 11通用相關
Edge Protect
iPhone X 剛出來的時候蘋果第一時間更新了新設備的交互文檔,其中針對了大家最關心的“系統手勢和App自帶手勢沖突”的問題也給出了相應的解決辦法:
[圖片上傳失敗...(image-30eb96-1518080414937)]
雖然蘋果用黑體字寫著強烈不建議開發者干涉系統的手勢,但是為了增強用戶體驗還是開出了接口,蘋果管這個叫做 "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是否延遲執行系統手勢。
[圖片上傳失敗...(image-96b904-1518080414937)]
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手勢的,但是當用戶誤觸到邊界的時候還是會稍稍影響體驗,尤其是在全屏模式下、相機、視頻、游戲等
[圖片上傳失敗...(image-832295-1518080414937)]
-
Edge Protent
在對應的ViewControll中添加如下代碼,我們這邊開啟的是所有邊界限制其中包括了上、下邊界。在下拉或者上拉的話會先觸發App內部手勢,同時出現一個小箭頭然后在箭頭消失之前再次滑動就會觸發系統手勢。
-(UIRectEdge)preferredScreenEdgesDeferringSystemGestures
{
return UIRectEdgeAll;
}
[圖片上傳失敗...(image-c842f2-1518080414937)]
setNeedsUpdateOfScreenEdgesDeferringSystemGestures
這個方法是在應用內部動態控制edge protect,我們可以在上個方法中返回一個BOOL變量,然后根據需要改變該變量的值,然后調用該方法進行刷新。
[圖片上傳失敗...(image-179588-1518080414937)]
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相關的任何手勢。
[圖片上傳失敗...(image-e2df61-1518080414937)]
后來看了其他游戲,視頻類App在iPhone X上的表現也都是如此。騰訊的王者榮耀,網易的吃雞都是一樣。騰訊官方給出的解釋是暫時開起引導式訪問,也仍然不方便。后來在今年1月25日蘋果推送了iOS 11.2.5的版本更新,然后王者榮耀也跟著進行了一波更新,在進入游戲時候就會發現,底部的Home Indicator當你一段時間不去觸碰它的時候由黑色或者白色(根據當前的屏幕顯示的內容來決定)變成非常透明的灰色,當你第一次進行操作會默認執行App內手勢,同時激活Home Indicator,短時間內進行第二次操作就可以返回桌面
[圖片上傳失敗...(image-343abc-1518080414937)]
一開以為是有新的API出現,不過看了交互文檔并沒有新的東西,而且小版本的系統更新應該也不會出現新的東西。所以找到了之前的edge protect 代碼運行后確實可以達到效果。對于視頻,游戲等App,確實可以起到很好的防誤觸的效果。遺憾的是并沒有太多的人使用這個功能。目前主流的大型游戲,包括Gameloft出品的游戲都沒做相應的處理。
[圖片上傳失敗...(image-3966df-1518080414937)]
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的滑動并不能觸發顯示,不過只是是隱藏,但是手勢依然可以使用。
[圖片上傳失敗...(image-51e7ac-1518080414938)]
如果是feed流界面搭配酷一點的UI就會提高沉浸感,比如這樣:
[圖片上傳失敗...(image-70ee2e-1518080414938)]
有的人可能會問如果說點擊的手勢會觸發它再次顯示那我獲取window上的交互每次在它即將顯示的時候通過setNeedsUpdateOfHomeIndicatorAutoHidden在讓他隱藏不就好了嗎?這樣一來既不影響系統手勢也不會讓它在顯示出來,其實我自己試過不行的,畢竟蘋果不會讓你這樣改。
坑點
需要注意的是:prefersHomeIndicatorAutoHidden和preferredScreenEdgesDeferringSystemGestures不可一起使用,如果一起使用的話后者是不生效的。