呈現(xiàn)一個(gè)視圖控制器
在屏幕上顯示視圖控制器有兩種方法:將其嵌入到容器視圖控制器中或者呈現(xiàn)它。容器視圖控制器提供了一個(gè)應(yīng)用程序的主要導(dǎo)航菩掏,但正在呈現(xiàn)的視圖控制器也是一個(gè)重要的導(dǎo)航工具。我們可以使用呈現(xiàn)來(lái)在當(dāng)前視圖控制器上層直接顯示一個(gè)新的視圖控制器。通常情況下族展,在實(shí)現(xiàn)模態(tài)界面時(shí),我們需要呈現(xiàn)一個(gè)視圖控制器拔鹰,但也可以將其用于其他目的仪缸。
UIViewController
類(lèi)支持呈現(xiàn)一個(gè)視圖控制器,并可用于所有視圖控制器對(duì)象列肢。我們可以使用任何視圖控制器來(lái)呈現(xiàn)其他的任何視圖控制器恰画,但UIKit可能會(huì)將呈現(xiàn)請(qǐng)求重新分配給不同的視圖控制器宾茂。正在呈現(xiàn)的視圖控制器會(huì)在它和呈現(xiàn)它的起始視圖控制器之間創(chuàng)建一種關(guān)系,正在呈現(xiàn)的視圖控制器是起始視圖控制器的presentedViewController
拴还,起始視圖控制器是正在呈現(xiàn)的視圖控制器的presentingViewController
跨晴。這種關(guān)系構(gòu)成了視圖控制器層次結(jié)構(gòu)的一部分,并保持原樣直到視圖控制器被從屏幕上移除片林。
呈現(xiàn)和轉(zhuǎn)場(chǎng)動(dòng)畫(huà)過(guò)程
呈現(xiàn)一個(gè)視圖控制器是將新內(nèi)容動(dòng)畫(huà)化到屏幕上的快捷方式端盆。內(nèi)置于UIKit中的呈現(xiàn)機(jī)制允許我們使用內(nèi)置或者自定義的動(dòng)畫(huà)顯示一個(gè)新的視圖控制器。實(shí)現(xiàn)內(nèi)置的呈現(xiàn)和動(dòng)畫(huà)只需要很少的代碼费封,UIKit會(huì)處理所有的工作焕妙。我們也可以創(chuàng)建自定義的呈現(xiàn)和動(dòng)畫(huà),只需要少許額外處理弓摘,就能將其用于任何視圖控制器访敌。
呈現(xiàn)樣式
視圖控制器的呈現(xiàn)樣式控制其在屏幕上的外觀。UIKit定義了許多標(biāo)準(zhǔn)的呈現(xiàn)樣式衣盾,每種風(fēng)格都有特定的外觀和意圖。我們也可以定義我們自己的自定義呈現(xiàn)樣式爷抓。在設(shè)計(jì)應(yīng)用程序時(shí)势决,請(qǐng)選擇最適合我們正在嘗試呈現(xiàn)的視圖控制器界面的樣式极景,并為視圖控制器的modalPresentationStyle
屬性分配合適的值筑累。
全屏樣式
全屏樣式覆蓋整個(gè)屏幕,防止與底層內(nèi)容的交互键闺。在水平常規(guī)環(huán)境中渤昌,只有一種全屏樣式完全覆蓋了底層內(nèi)容虽抄。其他的全屏樣式都包含遮罩視圖或透明視圖,以允許顯示一部分底層視圖控制器独柑。在水平緊湊環(huán)境中迈窟,全屏呈現(xiàn)會(huì)自動(dòng)適應(yīng)UIModalPresentationFullScreen
樣式并覆蓋所有底層內(nèi)容。
下圖顯示了在水平常規(guī)環(huán)境中使用UIModalPresentationFullScreen
忌栅,UIModalPresentationPageSheet
和UIModalPresentationFormSheet
樣式被呈現(xiàn)的視圖控制器的外觀车酣。在圖中,左上方的綠色視圖控制器呈現(xiàn)右上角的藍(lán)色視圖控制器索绪,每種呈現(xiàn)樣式的結(jié)果如下所示湖员。對(duì)于某些呈現(xiàn)樣式,UIKit會(huì)在兩個(gè)視圖控制器的內(nèi)容之間插入遮罩視圖瑞驱。
注意:使用
UIModalPresentationFullScreen
樣式來(lái)呈現(xiàn)視圖控制器時(shí)娘摔,UIKit通常會(huì)在轉(zhuǎn)場(chǎng)動(dòng)畫(huà)完成后刪除底層視圖控制器的視圖』椒矗可以通過(guò)指定UIModalPresentationOverFullScreen
樣式來(lái)防止刪除底層視圖凳寺。當(dāng)被呈現(xiàn)的視圖控制器具有讓底層視圖內(nèi)容顯示的透明區(qū)域時(shí)鸭津,可以使用此樣式。
當(dāng)使用一種全屏呈現(xiàn)樣式時(shí)读第,起始視圖控制器必須覆蓋整個(gè)屏幕曙博。如果起始視圖控制器沒(méi)有覆蓋整個(gè)屏幕,則UIKit逐步向上查看視圖控制器層次結(jié)構(gòu)怜瞒,直到找到一個(gè)有效的視圖控制器來(lái)全屏呈現(xiàn)另一個(gè)視圖控制器父泳。 如果找不到填充屏幕的中間視圖控制器,則UIKit將使用窗口的根視圖控制器吴汪。
Popover樣式
UIModalPresentationPopover
樣式在Popover中顯示視圖控制器惠窄。Popover對(duì)于顯示附加信息或者與焦點(diǎn)、選定對(duì)象相關(guān)的項(xiàng)目列表非常有用漾橙。在水平常規(guī)環(huán)境中杆融,Popover僅覆蓋部分屏幕,如下圖所示霜运。在水平緊湊的環(huán)境中脾歇,默認(rèn)情況下,Popover會(huì)適應(yīng)UIModalPresentationOverFullScreen
呈現(xiàn)樣式淘捡。點(diǎn)擊彈出視圖之外的屏幕會(huì)自動(dòng)移除Popover藕各。
因?yàn)镻opover會(huì)自動(dòng)適配在水平緊湊環(huán)境中的全屏呈現(xiàn),所以通常需要修改Popover代碼來(lái)處理適配焦除。在全屏模式下激况,需要一種方法來(lái)移除被呈現(xiàn)的Popover”炱牵可以通過(guò)添加一個(gè)按鈕乌逐,將Popover嵌入到一個(gè)可用的容器視圖控制器中,或者改變適配行為本身创葡。
當(dāng)前上下文樣式
UIModalPresentationCurrentContext
樣式覆蓋了界面中的特定視圖控制器浙踢。使用上下文樣式時(shí),通過(guò)將視圖控制器的definesPresentationContext
屬性值設(shè)為YES
來(lái)指定要覆蓋此視圖控制器蹈丸。下圖顯示了一個(gè)當(dāng)前上下文樣式的呈現(xiàn)成黄,它只覆蓋了分割視圖控制器的一個(gè)子視圖控制器。
注意:當(dāng)使用
UIModalPresentationFullScreen
樣式來(lái)呈現(xiàn)一個(gè)視圖控制器時(shí)逻杖,UIKit通常會(huì)在轉(zhuǎn)場(chǎng)動(dòng)畫(huà)執(zhí)行完成后刪除處于被呈現(xiàn)的視圖控制器之下的視圖控制器的視圖奋岁。可以通過(guò)指定UIModalPresentationOverCurrentContext
樣式來(lái)防止刪除這些視圖荸百。當(dāng)被呈現(xiàn)的視圖控制器具有讓底層內(nèi)容顯示的透明區(qū)域時(shí)闻伶,可以使用該樣式。
定義了呈現(xiàn)上下文的視圖控制器也可以定義在呈現(xiàn)過(guò)程中使用的轉(zhuǎn)場(chǎng)動(dòng)畫(huà)够话。通常情況下蓝翰,UIKit使用起始視圖控制器的modalTransitionStyle
屬性值來(lái)在屏幕上動(dòng)畫(huà)視圖控制器光绕。如果呈現(xiàn)上下文視圖控制器的providesPresentationContextTransitionStyle
屬性值為YES
,則UIKit將使用該視圖控制器的modalTransitionStyle
屬性值畜份。
當(dāng)切換到水平緊湊環(huán)境時(shí)诞帐,當(dāng)前上下文樣式會(huì)適應(yīng)UIModalPresentationFullScreen
樣式。要更改此行為爆雹,請(qǐng)使用自適應(yīng)呈現(xiàn)委托來(lái)指定不同的呈現(xiàn)樣式或視圖控制器停蕉。
自定義呈現(xiàn)樣式
UIModalPresentationCustom
樣式允許我們使用自己定義的自定義樣式來(lái)呈現(xiàn)一個(gè)視圖控制器。創(chuàng)建自定義樣式需要子類(lèi)化UIPresentationController
钙态,并使用其方法來(lái)將任何自定義視圖動(dòng)畫(huà)到屏幕上慧起,同時(shí)設(shè)置需要被呈現(xiàn)的視圖控制器的尺寸和位置。起始控制器還處理由于其所呈現(xiàn)的視圖控制器的特性的變化而發(fā)生的任何適應(yīng)册倒。
轉(zhuǎn)場(chǎng)動(dòng)畫(huà)樣式
轉(zhuǎn)場(chǎng)動(dòng)畫(huà)樣式確定了用于呈現(xiàn)一個(gè)視圖控制器的動(dòng)畫(huà)類(lèi)型蚓挤。對(duì)于官方提供的轉(zhuǎn)場(chǎng)動(dòng)畫(huà)樣式,可以將其中一種標(biāo)準(zhǔn)樣式分配給需要呈現(xiàn)的視圖控制器的modalTransitionStyle
屬性驻子。呈現(xiàn)一個(gè)視圖控制器時(shí)灿意,UIKit會(huì)創(chuàng)建與該樣式相對(duì)應(yīng)的動(dòng)畫(huà)。例如崇呵,下圖說(shuō)明了標(biāo)準(zhǔn)的UIModalTransitionStyleCoverVertical
轉(zhuǎn)場(chǎng)動(dòng)畫(huà)樣式如何為屏幕上的視圖控制器生成動(dòng)畫(huà)脾歧。視圖控制器B開(kāi)始進(jìn)入屏幕時(shí),動(dòng)畫(huà)滑動(dòng)到視圖控制器A的頂部上方演熟。當(dāng)視圖控制器B被移除時(shí),動(dòng)畫(huà)反轉(zhuǎn)司顿,以便B向下滑動(dòng)以顯示A芒粹。
可以使用動(dòng)畫(huà)對(duì)象和轉(zhuǎn)場(chǎng)動(dòng)畫(huà)委托對(duì)象來(lái)創(chuàng)建自定義轉(zhuǎn)場(chǎng)。動(dòng)畫(huà)對(duì)象創(chuàng)建用于將視圖控制器顯示到屏幕上的過(guò)渡動(dòng)畫(huà)大溜。轉(zhuǎn)場(chǎng)動(dòng)畫(huà)委托在適當(dāng)?shù)臅r(shí)候?qū)?dòng)畫(huà)對(duì)象提供給UIKit化漆。
呈現(xiàn)一個(gè)視圖控制器的方式
UIViewController類(lèi)提供了兩種方式來(lái)顯示視圖控制器:
-
showViewController:sender:
和showDetailViewController:sender:
方法提供了最適應(yīng)和最靈活的方式來(lái)顯示視圖控制器。這些方法讓起始控制器決定如何最好地處理呈現(xiàn)钦奋。例如座云,容器視圖控制器可以讓視圖控制器作為一個(gè)子視圖控制器來(lái)呈現(xiàn),而不是以模態(tài)方式呈現(xiàn)付材。默認(rèn)行為以模態(tài)方式呈現(xiàn)一個(gè)視圖控制器朦拖。 -
presentViewController:animated:completion:
方式總是模態(tài)顯示視圖控制器。調(diào)用此方法的視圖控制器可能最終不會(huì)處理此次呈現(xiàn)厌衔,但呈現(xiàn)始終是模態(tài)的璧帝。這種方法會(huì)適應(yīng)在水平緊湊環(huán)境中的呈現(xiàn)樣式。
showViewController:sender:
和showDetailViewController:sender:
方法是發(fā)起呈現(xiàn)的首選方式富寿。視圖控制器可以調(diào)用它們而不知道視圖控制器層次結(jié)構(gòu)的其余部分或當(dāng)前視圖控制器在該層次結(jié)構(gòu)中的位置睬隶。這些方法可以在不用編寫(xiě)附帶條件的代碼的情況下锣夹,在應(yīng)用程序的不同部分重新使用視圖控制器。
呈現(xiàn)一個(gè)視圖控制器
有以下幾種方式來(lái)發(fā)起視圖控制器的呈現(xiàn):
- 使用segue自動(dòng)呈現(xiàn)視圖控制器苏潜。segue使用在Interface Builder中指定的信息來(lái)實(shí)例化并呈現(xiàn)視圖控制器银萍。
- 使用
showViewController:sender:
和showDetailViewController:sender:
方法來(lái)顯示視圖控制器。在自定義視圖控制器中恤左,可以將這些方法的行為更改為更適合我們的視圖控制器的行為贴唇。 - 調(diào)用
presentViewController:animated:completion:
方法以模態(tài)方式呈現(xiàn)視圖控制器。
顯示視圖控制器
當(dāng)使用showViewController:sender:
和showDetailViewController:sender:
方法時(shí)赃梧,將新視圖控制器添加到屏幕上的過(guò)程很簡(jiǎn)單:
- 創(chuàng)建需要呈現(xiàn)的視圖控制器對(duì)象滤蝠。在創(chuàng)建視圖控制器時(shí),需要使用任何需要執(zhí)行其任務(wù)的數(shù)據(jù)對(duì)其進(jìn)行初始化授嘀。
- 將視圖控制器的
modalPresentationStyle
屬性設(shè)置為需要的樣式物咳。這種樣式可能不會(huì)在最終呈現(xiàn)中使用。 - 將視圖控制器的
modalTransitionStyle
屬性設(shè)置為需要的轉(zhuǎn)場(chǎng)動(dòng)畫(huà)樣式蹄皱。這種樣式可能不會(huì)在最終呈現(xiàn)中使用览闰。 - 調(diào)用當(dāng)前視圖控制器的
showViewController:sender:
和showDetailViewController:sender:
方法。
UIKit會(huì)將對(duì)showViewController:sender:
和showDetailViewController:sender:
方法的調(diào)用轉(zhuǎn)發(fā)給合適的視圖控制器巷折。該視圖控制器可以決定如何最好地執(zhí)行呈現(xiàn)压鉴,并可以根據(jù)需要更改呈現(xiàn)樣式和轉(zhuǎn)場(chǎng)動(dòng)畫(huà)樣式。例如锻拘,導(dǎo)航控制器可能會(huì)將視圖控制器推到其導(dǎo)航堆棧上油吭。
模態(tài)呈現(xiàn)視圖控制器
當(dāng)直接呈現(xiàn)視圖控制器時(shí),需要告訴UIKit如何顯示新的視圖控制器以及如何動(dòng)畫(huà)顯示到屏幕上:
- 創(chuàng)建需要呈現(xiàn)的視圖控制器對(duì)象署拟。在創(chuàng)建視圖控制器時(shí)婉宰,需要使用任何需要執(zhí)行其任務(wù)的數(shù)據(jù)對(duì)其進(jìn)行初始化。
- 將視圖控制器的
modalPresentationStyle
屬性設(shè)置為需要的樣式推穷。 - 將視圖控制器的
modalTransitionStyle
屬性設(shè)置為需要的轉(zhuǎn)場(chǎng)動(dòng)畫(huà)樣式心包。 - 調(diào)用當(dāng)前視圖控制器的
presentViewController:animated:completion:
方法。
調(diào)用presentViewController:animated:completion:
方法的視圖控制器可能不是實(shí)際發(fā)起模態(tài)呈現(xiàn)的視圖控制器馒铃。呈現(xiàn)樣式?jīng)Q定來(lái)如何呈現(xiàn)視圖控制器蟹腾,包括發(fā)起呈現(xiàn)的視圖控制器所需的特性。例如区宇,全屏呈現(xiàn)必須由覆蓋全屏的視圖控制器發(fā)起娃殖。如果當(dāng)前視圖控制器不合適,UIKit將遍歷視圖控制器層次結(jié)構(gòu)议谷,直到找到一個(gè)為止珊随。UIKit在完成模態(tài)呈現(xiàn)后,會(huì)更新受影響的視圖控制器的presentingViewController
和presentedViewController
屬性。
在Popover中呈現(xiàn)一個(gè)視圖控制器
在呈現(xiàn)Popover之前叶洞,需要一些額外配置鲫凶。在設(shè)置模態(tài)呈現(xiàn)樣式為UIModalPresentationPopover
后,配置以下與Popover相關(guān)的屬性:
- 將視圖控制器的
preferredContentSize
屬性設(shè)置為所需的尺寸衩辟。 - 訪問(wèn)視圖控制器的
popoverPresentationController
屬性獲得與其相關(guān)聯(lián)的UIPopoverPresentationController
對(duì)象螟炫,并使用該對(duì)象來(lái)設(shè)置Popover的錨點(diǎn)。只需要設(shè)置下列之一:- 將
barButtonItem
屬性值設(shè)為一個(gè)UIBarButtonItem
對(duì)象艺晴。 - 將
sourceView
屬性值設(shè)置為當(dāng)前視圖層中的某個(gè)視圖昼钻,sourceRect
屬性值設(shè)置為sourceView
中的某個(gè)特定區(qū)域。
- 將
可以使用UIPopoverPresentationController
對(duì)象根據(jù)需要對(duì)Popover的外觀進(jìn)行其他調(diào)整封寞。Popover控制器對(duì)象還支持設(shè)置委托對(duì)象來(lái)響應(yīng)在呈現(xiàn)過(guò)程中的更改然评。例如,當(dāng)Popover出現(xiàn)狈究、消失或在屏幕上重新定位時(shí)碗淌,可以使用委托對(duì)象來(lái)響應(yīng)。有關(guān)此對(duì)象的更多信息抖锥,可以參閱UIPopoverPresentationController Class Reference亿眠。
移除呈現(xiàn)的視圖控制器
要移除當(dāng)前呈現(xiàn)的視圖控制器,需要調(diào)用該視圖控制器的dismissViewControllerAnimated:completion:
方法磅废。也可以調(diào)用呈現(xiàn)該視圖控制器的起始視圖控制器的該方法來(lái)移除當(dāng)前被呈現(xiàn)的視圖控制器纳像。當(dāng)調(diào)用起始視圖控制器的該方法時(shí),UIKit會(huì)自動(dòng)將移除請(qǐng)求轉(zhuǎn)發(fā)給被呈現(xiàn)的視圖控制器拯勉。
在移除視圖控制器之前竟趾,請(qǐng)總是保持視圖控制器中的重要信息。移除視圖控制器會(huì)將其從視圖控制器層次結(jié)構(gòu)中刪除宫峦,并將其視圖從屏幕上移除潭兽。如果沒(méi)有強(qiáng)引用該視圖控制器,移除該視圖控制器將釋放與之關(guān)聯(lián)的內(nèi)存斗遏。
如果呈現(xiàn)的視圖控制器必須傳輸數(shù)據(jù)給發(fā)起呈現(xiàn)的視圖控制器,則使用委托設(shè)計(jì)模式來(lái)促進(jìn)傳輸鞋邑。委托可以使在應(yīng)用程序的不同部分來(lái)重用視圖控制器變得簡(jiǎn)單诵次。使用委托,被呈現(xiàn)的視圖控制器會(huì)存儲(chǔ)對(duì)實(shí)現(xiàn)來(lái)協(xié)議方法的委托對(duì)象的引用枚碗。當(dāng)被呈現(xiàn)的視圖控制器需要接收數(shù)據(jù)時(shí)逾一,其會(huì)調(diào)用委托對(duì)象的協(xié)議方法。
在不同storyboard文件中的視圖控制器之間發(fā)起呈現(xiàn)
可以在同一個(gè)storyboard文件中的視圖控制器之間創(chuàng)建segue肮雨,但不能在不同storyboard文件中的視圖控制器之間創(chuàng)建segue遵堵。當(dāng)需要呈現(xiàn)一個(gè)存儲(chǔ)在不同storyboard文件中的視圖控制器時(shí),必須在呈現(xiàn)其之前明確地實(shí)例化這個(gè)視圖控制器,如下所示陌宿。該示例以模態(tài)方式呈現(xiàn)視圖控制器锡足,但我們也可以將其推到導(dǎo)航堆棧上或以其他方式顯示。
UIStoryboard* sb = [UIStoryboard storyboardWithName:@"SecondStoryboard" bundle:nil];
MyViewController* myVC = [sb instantiateViewControllerWithIdentifier:@"MyViewController"];
// Configure the view controller.
// Display the view controller
[self presentViewController:myVC animated:YES completion:nil];
使用Segue
使用segue來(lái)定義應(yīng)用程序界面的跳轉(zhuǎn)流程壳坪。segue定義了storyboard文件中的兩個(gè)視圖控制器之間的轉(zhuǎn)換舶得。segue的起始點(diǎn)是啟動(dòng)segue的按鈕、表格行或者手勢(shì)識(shí)別器爽蝴。segue的結(jié)束點(diǎn)是想要顯示的視圖控制器沐批。segue總是呈現(xiàn)一個(gè)新的視圖控制器,但是也可以使用unwind segue來(lái)移除視圖控制器蝎亚。
不需要以編程方式觸發(fā)segue九孩。在運(yùn)行時(shí),UIKit加載與視圖控制器相關(guān)聯(lián)的segue发框,并將它們連接到相應(yīng)的元素躺彬。當(dāng)用戶與元素產(chǎn)生交互時(shí),UIKit會(huì)加載相應(yīng)的視圖控制器缤底,通知應(yīng)用程序即將觸發(fā)segue顾患,并執(zhí)行轉(zhuǎn)換「鲞螅可以使用UIKit發(fā)送的通知將數(shù)據(jù)傳遞到新的視圖控制器或者防止此種情況發(fā)生江解。
在視圖控制器之間創(chuàng)建一個(gè)segue
要在同一個(gè)storyboard文件中的視圖控制器之間創(chuàng)建一個(gè)segue,請(qǐng)按住Control
鍵并單擊第一個(gè)視圖控制器中的相應(yīng)元素徙歼,然后拖動(dòng)到目標(biāo)視圖控制器犁河。segue的起始點(diǎn)必須是具有已經(jīng)定義了action的視圖或者對(duì)象,例如control魄梯、bar button item或者gesture recognizer桨螺。也可以從基于單元格的視圖(如table view和collection view)創(chuàng)建segue。下圖顯示了創(chuàng)建一個(gè)當(dāng)單元格被點(diǎn)擊時(shí)顯示一個(gè)新視圖控制器的segue酿秸。
注意:某些元素支持關(guān)聯(lián)多個(gè)segue灭翔。例如,可以為cell上的button點(diǎn)擊配置一個(gè)segue辣苏,同時(shí)也可以為cell點(diǎn)擊配置另一個(gè)segue肝箱。
當(dāng)松開(kāi)鼠標(biāo)按鈕時(shí),Interface Builder會(huì)提示我們選擇要在兩個(gè)視圖控制器之間創(chuàng)建的關(guān)系類(lèi)型稀蟋,如下圖所示煌张。選擇符合我們需要的轉(zhuǎn)換的segue。
當(dāng)為segue選擇關(guān)系類(lèi)型時(shí)退客,盡可能選擇一個(gè)自適應(yīng)segue骏融。自適應(yīng)segue會(huì)根據(jù)當(dāng)前屏幕環(huán)境調(diào)整其行為链嘀。例如,Show segue的行為基于需要呈現(xiàn)的視圖控制器而改變档玻。非自適應(yīng)segue適用于必須在iOS 7系統(tǒng)運(yùn)行的應(yīng)用程序怀泊。以下列出了自適應(yīng)segue類(lèi)型以及它們?cè)趹?yīng)用程序中的行為:
-
Show (Push) : 該segue使用目標(biāo)視圖控制器的
showViewController:sender:
方法來(lái)顯示新的內(nèi)容。對(duì)于大多數(shù)視圖控制器窃肠,該segue在源視圖控制器上以模態(tài)方式呈現(xiàn)新內(nèi)容包个。一些視圖控制器專(zhuān)門(mén)覆蓋該方法并使用它來(lái)實(shí)現(xiàn)不同的行為。例如冤留,導(dǎo)航控制器將新的視圖控制器推到其導(dǎo)航堆棧上碧囊。UIKit使用targetViewControllerForAction:sender:
方法來(lái)定位源視圖控制器。 -
Show Detail (Replace) : 該segue使用目標(biāo)視圖控制器的
showDetailViewController:sender:
方法來(lái)顯示新的內(nèi)容纤怒。其僅與嵌入在UISplitViewController
對(duì)象內(nèi)的視圖控制器有關(guān)糯而。通過(guò)該segue,分割視圖控制器用新的內(nèi)容替換它的第二個(gè)子視圖控制器(細(xì)節(jié)控制器)泊窘。大多數(shù)其他控制器以模態(tài)方式呈現(xiàn)新內(nèi)容熄驼。UIKit使用targetViewControllerForAction:sender:
方法來(lái)定位源視圖控制器。 - Present Modally : 該segue使用指定的呈現(xiàn)樣式和轉(zhuǎn)場(chǎng)動(dòng)畫(huà)樣式以模態(tài)方式顯示視圖控制器烘豹。定義了相應(yīng)的呈現(xiàn)上下文的視圖控制器會(huì)處理實(shí)際的呈現(xiàn)瓜贾。
- Present as Popover : 在水平常規(guī)屏幕環(huán)境中,視圖控制器顯示在Popover中携悯。在水平緊湊屏幕環(huán)境中祭芦,視圖控制器使用全屏呈現(xiàn)樣式來(lái)被顯示。
創(chuàng)建一個(gè)segue之后憔鬼,選中segue對(duì)象并使用屬性檢查器為其分配一個(gè)標(biāo)識(shí)符龟劲。在執(zhí)行segue時(shí),可以使用標(biāo)識(shí)符來(lái)確定哪個(gè)segue被觸發(fā)轴或。如果視圖控制器支持多個(gè)segue昌跌,那么這樣做是特別有用的。標(biāo)識(shí)符包含在執(zhí)行segue時(shí)傳遞給視圖控制器的UIStoryboardSegue
對(duì)象中照雁。
在運(yùn)行時(shí)修改segue的行為
下圖顯示了當(dāng)一個(gè)segue被觸發(fā)時(shí)發(fā)生了什么蚕愤。大多數(shù)工作發(fā)生在發(fā)起呈現(xiàn)的視圖控制器中,其管理著到新視圖控制器的轉(zhuǎn)場(chǎng)饺蚊。新視圖控制器的配置與以編碼方式創(chuàng)建視圖控制器并呈現(xiàn)它的過(guò)程基本相同萍诱。由于是在storyboard文件中配置segue,所以與segue關(guān)聯(lián)的兩個(gè)視圖控制器必須在同一個(gè)storyboard文件中卸勺。
在執(zhí)行segue期間,UIKit調(diào)用當(dāng)前視圖控制器的方法來(lái)提供機(jī)會(huì)讓我們影響segue的結(jié)果烫扼。
-
shouldPerformSegueWithIdentifier:sender:
方法提供了阻止segue執(zhí)行的機(jī)會(huì)曙求。該方法返回NO
會(huì)導(dǎo)致segue執(zhí)行失敗,但不會(huì)阻止其他行為的發(fā)生。例如悟狱,點(diǎn)擊tableview的cell仍然會(huì)導(dǎo)致tableview調(diào)用任何相關(guān)的委托方法静浴。 - 源視圖控制器的
prepareForSegue:sender:
方法允許我們將數(shù)據(jù)從源視圖控制器傳遞到目標(biāo)視圖控制器。傳遞給該方法的UIStoryboardSegue
對(duì)象包含對(duì)目標(biāo)視圖控制器的引用以及其他與segue相關(guān)的信息挤渐。
創(chuàng)建一個(gè)unwind segue
unwind segue能夠移除已經(jīng)被呈現(xiàn)的視圖控制器苹享。可以在Interface Builder中通過(guò)關(guān)聯(lián)一個(gè)按鈕或者其他合適的對(duì)象到當(dāng)前視圖控制器的Exit對(duì)象來(lái)創(chuàng)建unwind segue浴麻。當(dāng)用戶點(diǎn)擊按鈕或者與適當(dāng)?shù)膶?duì)象交互時(shí)得问,UIKit會(huì)搜索視圖控制器層次結(jié)構(gòu)來(lái)找到一個(gè)能夠處理unwind segue的對(duì)象。然后移除當(dāng)前視圖控制器和任何中間視圖控制器來(lái)展示與unwind segue關(guān)聯(lián)的目標(biāo)視圖控制器软免。
創(chuàng)建一個(gè)unwind segue遵循以下步驟:
- 選擇unwind segue執(zhí)行結(jié)束后應(yīng)該顯示在屏幕上的視圖控制器宫纬。
- 在選擇的視圖控制器中定義一個(gè)unwind 操作方法,這個(gè)操作方法的Objective-C語(yǔ)法為
- (IBAction)myUnwindAction:(UIStoryboardSegue*)unwindSegue
- 導(dǎo)航到發(fā)起unwind segue的視圖控制器膏萧。
- 按住Control鍵點(diǎn)擊執(zhí)行unwind segue的按鈕(或其他對(duì)象)漓骚。該按鈕(或其他對(duì)象)應(yīng)該存在于需要被移除的視圖控制器中。
- 拖動(dòng)到視圖控制器頂部的
Exit
對(duì)象榛泛。 - 在relationship panel中選擇unwind操作方法蝌蹂。
在Interface Builder中創(chuàng)建相應(yīng)的unwind segue之前,必須在發(fā)起unwind segue的視圖控制器中定義一個(gè)unwind操作方法曹锨。該方法的存在是必需的孤个,其告知Interface Builder有一個(gè)有效的unwind segue目標(biāo)。
使用unwind操作方法的實(shí)現(xiàn)來(lái)執(zhí)行應(yīng)用程序中特定的任何任務(wù)艘希。UIKit會(huì)自動(dòng)移除視圖控制器硼身,而不需要我們手動(dòng)移除發(fā)起segue的任何視圖控制器「蚕恚可以使用segue對(duì)象獲取正在被移除的視圖控制器佳遂,以便從其中回收數(shù)據(jù)。也可以使用unwind操作方法在unwind segue結(jié)束之前更新當(dāng)前視圖控制器撒顿。
以編程方式發(fā)起segue
segue通常是由在storyboard文件中創(chuàng)建的連接觸發(fā)的丑罪。但是,有時(shí)可能無(wú)法在storyboard文件中創(chuàng)建segue凤壁,可能是因?yàn)闊o(wú)法確定目標(biāo)視圖控制器吩屹。例如,游戲應(yīng)用程序可能會(huì)根據(jù)游戲的結(jié)果轉(zhuǎn)場(chǎng)到不同的界面拧抖。在這些情況下煤搜,可以使用當(dāng)前視圖控制器的performSegueWithIdentifier:sender:
方法編程方式出發(fā)segue。
以下代碼演示了從縱向到橫向旋轉(zhuǎn)時(shí)呈現(xiàn)特定視圖控制器的segue唧席。因?yàn)檫@種情況下的通知對(duì)象沒(méi)有提供執(zhí)行segue命令的有用信息擦盾,視圖控制器就將自己指定為segue的發(fā)起者嘲驾。
- (void)orientationChanged:(NSNotification *)notification
{
UIDeviceOrientation deviceOrientation = [UIDevice currentDevice].orientation;
if (UIDeviceOrientationIsLandscape(deviceOrientation) && !isShowingLandscapeView)
{
[self performSegueWithIdentifier:@"DisplayAlternateView" sender:self];
isShowingLandscapeView = YES;
}
// Remainder of example omitted.
}
創(chuàng)建自定義的segue
Interface Builder提供了從一個(gè)視圖控制器轉(zhuǎn)換到另一個(gè)視圖控制器的所有標(biāo)準(zhǔn)方式。如果這些方式不能滿足需求迹卢,也可以創(chuàng)建一個(gè)自定義segue辽故。
segue的生命周期
要理解自定義segue如何工作,就需要了解segue對(duì)象的生命周期腐碱。segue對(duì)象是UIStoryboardSegue
類(lèi)或其子類(lèi)的實(shí)例誊垢,應(yīng)用程序永遠(yuǎn)不會(huì)直接創(chuàng)建segue對(duì)象。當(dāng)一個(gè)segue被觸發(fā)時(shí)症见,UIKit會(huì)自動(dòng)創(chuàng)建segue對(duì)象喂走。以下是segue被觸發(fā)時(shí)所發(fā)生的事情:
- 創(chuàng)建并初始化需要呈現(xiàn)的視圖控制器。
- 創(chuàng)建segue對(duì)象并調(diào)用其
initWithIdentifier:source:destination:
方法來(lái)初始化筒饰。identifier
是在Interface Builder中為segue提供的唯一字符串缴啡,另外兩個(gè)參數(shù)為參與轉(zhuǎn)換的兩個(gè)視圖控制器對(duì)象。 - 調(diào)用發(fā)起呈現(xiàn)的視圖控制器的
prepareForSegue:sender:
方法瓷们。 - 調(diào)用segue對(duì)象的
perform
方法业栅。該方法執(zhí)行轉(zhuǎn)換以將新的視圖控制器顯示在屏幕上。 - 釋放被引用的segue對(duì)象谬晕。
實(shí)現(xiàn)一個(gè)自定義segue
為了實(shí)現(xiàn)一個(gè)自定義segue碘裕,需要子類(lèi)化UIStoryboardSegue
并實(shí)現(xiàn)以下方法:
- 覆寫(xiě)
initWithIdentifier:source:destination:
方法,并使用該方法來(lái)初始化自定義的segue對(duì)象攒钳。需要首先調(diào)用super
帮孔。 - 實(shí)現(xiàn)
perform
方法并使用該方法來(lái)配置轉(zhuǎn)場(chǎng)動(dòng)畫(huà)。
注意:如果自定義segue類(lèi)中添加了配置segue的屬性不撑,是無(wú)法在Interface Builder中配置這些屬性的文兢。但可以在觸發(fā)segue的源視圖控制器的
prepareForSegue:sender:
方法中配置自定義segue的附加屬性。
以下代碼展示了一個(gè)簡(jiǎn)單的自定義segue焕檬,其只是簡(jiǎn)單的呈現(xiàn)了目標(biāo)視圖控制器姆坚,沒(méi)有使用任何動(dòng)畫(huà),但可以根據(jù)需要來(lái)擴(kuò)展該它实愚。
- (void)perform
{
// Add your own animation code here.
[[self sourceViewController] presentViewController:[self destinationViewController] animated:NO completion:nil];
}