原文連接: Preventing Popovers on Popovers
原文做者: Douglas Hill
譯文出自: 掘金翻譯計劃
譯者: llp0574
校對者: yifili09,Graning
譯者注:轉載請保留此頭部。ios
iOS 9 的頁面用了一種咱們不能復現的方式去展現一個活動視圖控制器,而且當從內部表單和彈窗呈現操做列表和活動視圖控制器時 UIKit 的行爲一開始看起來不那麼連貫。咱們提交了兩份 Radars 給蘋果:rdar://27448912 Can’t show activity view controller filling a form sheet 和 rdar://27448488 Reading an alert controller’s popoverPresentationController property changes behavior。git
iOS 的人機交互指南聲明:github
不要在一個彈窗上展現一個模態視圖。 因爲一個警告彈窗多是一個異常,因此不該該在這上面展示任何東西。極少數狀況下,當你真的須要在一個動做致使彈窗後展現一個模態視圖時,應該先把彈窗關閉掉再進行展現。app
而且:iview
一次只展現一個彈窗。 展現多個彈窗會讓交互變得雜亂並讓人產生疑惑。千萬不要展現一個級聯或者有層次結構的彈窗,一個從另外一個裏面產生的那種。若是你須要展現一個新的彈窗,首先關閉已經彈出的那個。ide
在橫向水平的普通環境和全屏緊湊的環境下具備彈窗樣式的視圖控制器都應該呈現爲彈窗。具備操做列表樣式的 UIActivityViewController
和 UIAlertController
都遵照相同的規則:展現爲彈窗或者一個上拉式表。因此若是一個彈窗展現一個活動視圖控制器或者一個操做列表到底會發生什麼?這我的機交互指南文檔的說法好像有點矛盾。ui
在 iOS 9 頁面的一個相關說明裏,咱們注意到在一個表單的視圖控制器展現了一個填充了這個表單的 UIActivityViewController
,想知道這是否是一個咱們以前沒有留意到的默認行爲呢?又或者它是否是一個咱們能夠自定義實現的東西?spa
對於大多數視圖控制器來講,在裏面展現一個彈窗或者表單須要將當前視圖控制器的 modalPresentationStyle
設置爲 currentContext
或者 overCurrentContext
。但對於某些像 UIActivityViewController
和 UIAlertController
這種 UIKit 提供的視圖控制器來講,它們已經被賦予了本身的樣式,modalPresentationStyle
的變化將被忽略掉。翻譯
通常,UIActivityViewController
會在常規寬度下展現爲彈窗,在緊湊寬度下變成一個透明的表。可是若是一個常規寬度的視圖控制器要從一個緊湊寬度的視圖控制器裏展現會怎麼樣呢?這種狀況會在一個有表格或者彈窗 的 modalPresentationStyle
的視圖控制器要在 iPad 上展現,或者它是一個使用了 overrideTraitCollection
屬性的自定義展現控制器,而後這個控制器展現了一個 UIActivityViewController
。code
首先咱們來看看 UIAlertController
。圖中根視圖控制器(青色)用彈窗樣式(下方,經過切分視圖行爲以做參考)展現了第二個用表單樣式(上方)的視圖控制器(粉色)。而後第二個視圖控制器展現了一個操做列表樣式的警告控制器。
雖然咱們想要用列表的展現樣式去展現操做列表(而不是彈窗),但由於關注點分離的優點,我設置了警告控制器的 popoverPresentationController.sourceView
和 popoverPresentationController.sourceRect
,視圖控制器不該該對它怎麼展現做出假設。它應該在 app 的其餘部分進行全屏展現,視圖控制器不該該控制這些行爲。
出於好奇,我嘗試註釋掉了popoverPresentationController
的定義,發生了讓我意想不到的狀況:
原來只讀取警告控制器的popoverPresentationController
屬性會致使即便是從一個緊湊寬度環境下呈現它也會展現爲一個彈窗。若是你想這麼作,請必定要確保好視圖控制器展示的先後環境,由於若是你想從常規寬度的環境展示一個沒有設置彈窗源碼的警告控制器,UIKit 就會拋出一個異常。切記在展示觸發的時候即便呈現視圖控制器是在一個緊湊寬度環境下,當展現被激活的時候它仍是有可能發生改變。
用UIActivityViewController
作一樣的事情,並指定彈窗源碼信息,出現下面的狀況:
不一樣於頁面的行爲,我發現表單把這個活動視圖控制器展現爲一個彈窗,彈窗將活動視圖控制器展現在表單上。這是在 iOS 10 的新行爲,iOS 9 裏,是從另外一個彈窗展現一個彈窗。
用一樣不訪問popoverPresentationController
的技巧致使 UIKit 拋出一個異常說「必須爲這個彈窗提供位置信息」。
咱們發現當 UIKit 的視圖控制器是從一個展現在常規寬度環境的緊湊寬度的環境中展現時行爲會變得很混亂。彈窗展示的通常規則是在常規寬度下展現爲彈窗,在緊湊寬度下爲全屏(儘管結合當前上下環境更有意義)。操做列表和活動視圖控制器的展現有點像彈窗的展現,但不要徹底按照通常的規則來展現。
實際的行爲看起來像是和人機交互指南說的同樣,並很大程度上忽略了特徵集合的 Size 類。UIKit 不會在操做列表的異常警告上展示一個彈窗。Size 類並不能控制全部的東西。
咱們不能重現頁面(Pages)的行爲。對於咱們來講,當一個表單展現一個活動視圖控制器時,它將展現爲彈窗。我把這個問題報告給了 Apple :rdar://27448912 Can’t show activity view controller filling a form sheet。若是你知道解決這個問題的方法,麻煩在個人 Twitter 留言。