iOS 9的頁面用了一種我們不能復(fù)現(xiàn)的方式去展示一個(gè)活動(dòng)視圖控制器,并且當(dāng)從內(nèi)部表單和彈窗呈現(xiàn)操作列表和活動(dòng)視圖控制器時(shí)UIKit的行為一開始看起來不那么連貫。我們提交了兩份Radars給蘋果:Can't show activity view controller filling a form sheet 和 Reading an alert controller's popov
ERPresentationController property changes behavior.
iOS的人機(jī)交互指南聲明:
不要在一個(gè)彈窗上展示一個(gè)模態(tài)視圖。 由于一個(gè)警告彈窗可能是一個(gè)異常,所以不應(yīng)該在這上面展現(xiàn)任何東西。極少數(shù)情況下,當(dāng)你真的需要在一個(gè)動(dòng)作導(dǎo)致彈窗后展示一個(gè)模態(tài)視圖時(shí),應(yīng)該先把彈窗關(guān)閉掉再進(jìn)行展示。
并且
一次只展示一個(gè)彈窗。 展示多個(gè)彈窗會(huì)讓交互變得雜亂并讓人產(chǎn)生疑惑。千萬不要展示一個(gè)級(jí)聯(lián)或者有層次結(jié)構(gòu)的彈窗,一個(gè)從另一個(gè)里面產(chǎn)生的那種。如果你需要展示一個(gè)新的彈窗,首先關(guān)閉已經(jīng)彈出的那個(gè)。
在橫向水平的普通環(huán)境和全屏緊湊的環(huán)境下具有彈窗樣式的視圖控制器都應(yīng)該呈現(xiàn)為彈窗。具有操作列表樣式的UIActivityViewController和UIAlertController都遵守相同的規(guī)則:展示為彈窗或者一個(gè)上拉式表。所以如果一個(gè)彈窗展示一個(gè)活動(dòng)視圖控制器或者一個(gè)操作列表到底會(huì)發(fā)生什么?這個(gè)人機(jī)交互指南文檔的說法好像有點(diǎn)矛盾。
在iOS 9頁面的一個(gè)相關(guān)說明里,我們注意到在一個(gè)表單的視圖控制器展示了一個(gè)填充了這個(gè)表單的UIActivityViewController,想知道這是不是一個(gè)我們之前沒有留意到的默認(rèn)行為呢?又或者它是不是一個(gè)我們可以自定義實(shí)現(xiàn)的東西?
對(duì)于大多數(shù)視圖控制器來說,在里面展示一個(gè)彈窗或者表單需要將當(dāng)前視圖控制器的modalPresentationStyle設(shè)置為currentContext或者overCurrentContext。但對(duì)于某些像UIActivityViewController和UIAlertController這種UIKit提供的視圖控制器來說,它們已經(jīng)被賦予了自己的樣式,modalPresentationStyle的變化將被忽略掉。
一般,UIActivityViewController會(huì)在常規(guī)寬度下展示為彈窗,在緊湊寬度下變成一個(gè)透明的表。但是如果一個(gè)常規(guī)寬度的視圖控制器要從一個(gè)緊湊寬度的視圖控制器里展示會(huì)怎么樣呢?這種情況會(huì)在一個(gè)有表格或者彈窗的modalPresentationStyle的視圖控制器要在iPad上展示,或者它是一個(gè)使用了overrideTraitCollection屬性的自定義展示控制器,然后這個(gè)控制器展示了一個(gè)UIActivityViewController。
操作列表
首先我們來看看UIAlertController。圖中根視圖控制器(青色)用彈窗樣式(下方,通過切分視圖行為以作參考)展示了第二個(gè)用表單樣式(上方)的視圖控制器(粉色)。然后第二個(gè)視圖控制器展示了一個(gè)操作列表樣式的警告控制器。
雖然我們想要用列表的展示樣式去展示操作列表(而不是彈窗),但因?yàn)殛P(guān)注點(diǎn)分離的優(yōu)勢(shì),我設(shè)置了警告控制器的popov
ERPresentationController.sourceView和popov
ERPresentationController.sourceRect,視圖控制器不應(yīng)該對(duì)它怎么展示作出假設(shè)。它應(yīng)該在app的其他部分進(jìn)行全屏展示,視圖控制器不應(yīng)該控制這些行為。
出于好奇,我嘗試注釋掉了popoverPresentationController的定義,發(fā)生了讓我意想不到的情況:
原來只讀取警告控制器的popoverPresentationController屬性會(huì)導(dǎo)致即使是從一個(gè)緊湊寬度環(huán)境下呈現(xiàn)它也會(huì)展示為一個(gè)彈窗。如果你想這么做,請(qǐng)一定要確保好視圖控制器展現(xiàn)的前后環(huán)境,因?yàn)槿绻阆霃某R?guī)寬度的環(huán)境展現(xiàn)一個(gè)沒有設(shè)置彈窗源碼的警告控制器,UIKit就會(huì)拋出一個(gè)異常。切記在展現(xiàn)觸發(fā)的時(shí)候即使呈現(xiàn)視圖控制器是在一個(gè)緊湊寬度環(huán)境下,當(dāng)展示被激活的時(shí)候它還是有可能發(fā)生改變。
我提交了一個(gè)rdar:Reading an alert controller's popoverPresentationController property changes behavior.
活動(dòng)視圖控制器
用UIActivityViewController做同樣的事情,并指定彈窗源碼信息,出現(xiàn)下面的情況:
不同于頁面的行為,我發(fā)現(xiàn)表單把這個(gè)活動(dòng)視圖控制器展示為一個(gè)彈窗,彈窗將活動(dòng)視圖控制器展示在表單上。這是在iOS 10的新行為,iOS 9里,是從另一個(gè)彈窗展示一個(gè)彈窗。
用同樣不訪問popoverPresentationController的技巧導(dǎo)致UIKit拋出一個(gè)異常說“必須為這個(gè)彈窗提供位置信息”。
結(jié)論
我們發(fā)現(xiàn)當(dāng)UIKit的視圖控制器是從一個(gè)展示在常規(guī)寬度環(huán)境的緊湊寬度的環(huán)境中展示時(shí)行為會(huì)變得很混亂。彈窗展現(xiàn)的一般規(guī)則是在常規(guī)寬度下展示為彈窗,在緊湊寬度下為全屏(盡管結(jié)合當(dāng)前上下環(huán)境更有意義)。操作列表和活動(dòng)視圖控制器的展示有點(diǎn)像彈窗的展示,但不要完全按照一般的規(guī)則來展示。
實(shí)際的行為看起來像是和人機(jī)交互指南說的一樣,并很大程度上忽略了特征集合的Size類。UIKit不會(huì)在操作列表的異常警告上展現(xiàn)一個(gè)彈窗。Size類并不能控制所有的東西。
我們不能重現(xiàn)頁面(Pages)的行為。對(duì)于我們來說,當(dāng)一個(gè)表單展示一個(gè)活動(dòng)視圖控制器時(shí),它將展示為彈窗。我把這個(gè)問題報(bào)告給了Apple(Radar:Can't show activity view controller filling a form sheet)。
轉(zhuǎn)載請(qǐng)注明出處:拓步ERP資訊網(wǎng)http://www.ezxoed.cn/
本文標(biāo)題:iOS開發(fā)中,如何解決彈窗設(shè)計(jì)問題?
本文網(wǎng)址:http://www.ezxoed.cn/html/support/11121519853.html