2012-03-16 62 views
32

安裝程序:我有一個故事板設置,有兩個簡單的視圖控制器A和B. A中有一個按鈕,通過模態漸變過渡到B. B在A之上呈現模態轉換。它很好。如何解除用模態segue呈現在UIStoryboard中的模態?

問題:有沒有一種方法可以讓B離開並用一些簡單的故事板魔法回到A?

請注意,如果這全部都在導航控制器中,並且我使用了推入塞格,那麼它將隱式地由導航控制器處理。會有一個「後退」按鈕。沒有什麼可比的模式,我需要自己建立UI,這很好,但我想知道是否有一個可以用信號從B回到A的信號機制。

現在使用oldskool方法構建的B回到A將是:

  • 基於B創建一個委託財產
  • 集A是B的代表時,模式轉變SEGUE回放(我可以掛接到這一點使用prepareForSegue:發件人:在A的代碼)
  • 當它是時候解僱,B信號給它的代表
  • A實現了一個委託方法,即解散B

這可行,但感覺像太多的開銷和愚蠢。

是否有一些UIStoryboard機制,我錯過了,基本上會做一個「反向模態賽格」?

回答

44

有沒有任何故事板魔術解除一個模態視圖控制器沒有寫至少一點點的代碼。

但是,雖然你必須實現自己的一些代碼,你不一定要去那麼多麻煩。您可以在視圖控制器B中只有一個調用[self dismissViewControllerAnimated:YES completion:nil]的按鈕。 (文檔中說,呈現視圖控制器應該是一個可以解散的視圖控制器,但是他們也會說,如果被邀請者被調用,該消息將被轉發給呈現視圖控制器。如果你想更清楚地瞭解它 - 會需要在某些情況下,當一個模態視圖控制器從另一個呈現喜歡 - 你可以明確地從那裏引用主持人與self.presentingViewController並調用dismiss...

您在一些應用程序看到的委託業務,因爲它是一個。在視圖控制器B中關於用戶所做的任何事情通知視圖控制器A的方式......但這不是唯一的方法。有KVO,通知,或簡單地調用A的方法後引用self.presentingViewController(假設B知道它總是由A呈現)。如果A不需要知道B中發生了什麼(例如,因爲用戶點擊取消按鈕),則無需執行任何操作 - 您可以關閉模​​式並完成相應操作。


在iOS 6中和以後,放鬆塞格斯添加另一種選擇,提供的「故事板魔術」一點點解僱模態視圖控制器(或以其他方式塞格斯的序列的「回退」)。但是這種方法仍然需要一些代碼 - 你無法完全在故事板中進行設置。儘管如此,從代碼的角度來看,從視圖控制器獲取信息被解散(B)到提供信息的途徑(A)。

蘋果a tech note about unwind segues覆蓋它們的細節,但這裏的短版本:

  1. 定義你想放鬆視圖控制器類的IBAction方法 - 呈現一個模式的一個視圖控制器,而不是模態視圖控制器本身(視圖控制器在你的問題)。與正常的IBAction方法不同,這些方法應採用UIStoryboardSegue *類型的參數;例如

    - (IBAction)unwindToMainMenu:(UIStoryboardSegue*)sender 
    
  2. 在所提出的視圖控制器(在問題B),金屬絲的控制綠色退出圖標,然後選擇你定義的方法。

  3. 在您的展開方法實現中,您可以參考segue的sourceViewController來從視圖控制器中檢索被解散的信息。您無需致電dismissViewControllerAnimated:completion:,因爲segue可以解除正在消失的視圖控制器。

+0

很酷,不知道呈現ViewController(顯然是一個新的iOS 5的東西),這有助於。 – Jaanus 2012-03-16 06:28:23

+2

是的,如果你想將它作爲一個自定義的繼續以方便重用,你可以做一些類似於 - (void)執行{UIViewController * src =(UIViewController *)self.sourceViewController; [src.presentingViewController dismissModalViewControllerAnimated:YES]; } – AppHandwerker 2012-08-10 14:02:58

+0

@SimonH關於segues的最佳建議! – 2012-10-06 21:19:13

30

故事板魔法來實現這一目標。它被稱爲放鬆賽。在A的.h文件中,您可以實現所需的任何「目標動作」風格方法,但無論您需要多少放鬆方式。對於一個模式,通常是兩個(取消和保存)。所以在我的文件啊我要補充:

// A.h file 
- (IBAction)myCancelUnwindSegueCallback:(UIStoryboardSegue *)segue; 
- (IBAction)mySaveUnwindSegueCallback:(UIStoryboardSegue *)segue; 

現在,在你的故事板,如果你從A到B.現在,您可以從您的取消/保存按鈕做了「目標行動」的風格控制拖動SEGUE在B中到故事板中B控制器底部的綠色「退出」圖標。當你這樣做的時候,Xcode會選擇我們創建的兩個方法(因爲它們在A的頭文件中,並且它們有正確的簽名(例如IBAction和UIStoryboardSegue *),而B是來自A的segue的目的地)你有它。你有你想要的故事板魔法!

在兩個回調的實現,你會的東西,如:

// A.m file 
- (IBAction)myCancelUnwindSegueCallback:(UIStoryboardSegue *)segue { 
    UIViewController *modalGoingAway = segue.sourceViewController; 
    // Do something (like get data) from modalGoingAway if you need to... 
} 

- (IBAction)mySaveUnwindSegueCallback:(UIStoryboardSegue *)segue { 
    UIViewController *modalGoingAway = segue.sourceViewController; 
    // Do something (like get data) from modalGoingAway if you need to... 
} 

最後,如果這種方法滿足你的需求,偉大的。你完成了。但是,如果「取消」或「保存」時我仍然連線整個協議委託/數據源設計模式,我希望在將控制權交給A以將B從視圖層次結構中移除之前,對B的私有屬性執行一些操作。

+1

請注意2件事: 1)在回調中,沒有必要關閉模式,因爲它會被自動解除順序繼續(如果你嘗試,會導致錯誤) 2)解除繼續動作(綠色退出按鈕)與iOS6一起使用目標。它有點令人困惑,因爲對於較老的目標,你會看到綠色的退出按鈕,這是沒有意義的) – 2014-02-02 12:05:56

+1

這不是真正的完整的「故事板魔法」,因爲你仍然需要向你的A視圖控制器添加代碼。但就我而言,B只是靜態內容,所以這不得不創建一個B視圖控制器子類來解僱它。 – jab 2014-03-08 23:27:42