2008-10-28 82 views
7

一週前我有點搔着頭,現在又多了一點可可的經驗,我覺得我對可能發生的事情有了一定的瞭解。parentViewController總是一個導航控制器?

我正在製作一個由UINavigationController驅動的應用程序。在AppDelegate中,我使用「頁面1」作爲根視圖控制器創建此類的一個實例。

UINavigationController *aNavigationController = [[UINavigationController alloc] 
    initWithRootViewController:page1ViewController]; 

現在,這裏是我遇到問題的地方。從「頁面1」我想使用一個模式視圖控制器,滑過界面,然後一旦用戶編輯就消失。我這樣做,使用這樣的代碼,Page1ViewController內:

[self presentModalViewController:myModalViewController animated:YES]; 

當模態視圖控制器走了,我想在「1」的值基於什麼用戶在模態視圖控制器進入改變。所以,我寫了一些這樣的代碼,它駐留在模態視圖控制器:

[self.parentViewController dismissModalViewControllerAnimated:YES]; 
[self.parentViewController doSomethingPleaseWithSomeData:someData]; 

第1頁更新沒有發生,而且我花了很長時間才意識到「doSomethingPleaseWithSomeData」消息是沒有被髮送到Page1ViewController,但導航控制器。

使用導航控制器時總是會有這種情況嗎?我是否可能配置不正確的東西?有沒有一種簡單的方法來獲得我想要的視圖控制器(在這種情況下,Page1ViewController)。

回答

14

我會推薦使用委託模式來解決您的問題。當用戶與您的視圖完成創建屬性

@property (nonatomic, assign) id <MyModalViewDelegate> delegate; 

和相應的協議

@protocol MyModalViewDelegate 
@optional 
    - (void)myModalViewControllerDidFinish:(MyModalViewController *)aModalViewController; 
@end 

(如水龍頭保存按鈕),發送此消息:

if ([self.delegate respondsToSelector:@selector(myModalViewControllerDidFinish:)]) 
    [self.delegate myModalViewControllerDidFinish:self]; 

現在,設置委託給應該管理整個事物的視圖控制器,並且在視圖控制器完成時它會被通知。請注意,您需要使用視圖控制器來關閉模式視圖控制器。但從邏輯上講,這是有道理的,因爲它首先呈現了模態視圖控制器。

這就是蘋果如何解決這個問題,例如,UIImagePickerController和UIPersonPickerController。

4

有幾種方法可以處理這個問題。最簡單的可能只是一個UIViewController屬性添加到myModalViewController並將其設置爲page1Controller您介紹它之前:

myModalViewController.logicalParent = self; //page1Controller 
[self presentModalViewController:myModalViewController animated:YES]; 

只要確保你的logicalParent添加相應的實例變量@property和@synthesize到myModalViewController,然後您將有一種方法將數據傳回給觸發模態對話框的ViewController。這也是爲了在不同級別的導航之間來回傳遞數據,然後將它們推入堆棧並將它們彈出。

做這件事時要擔心的一件重要事情是,如果你不小心,很容易得到保留環。根據你的結構,你可能需要使用賦值屬性。

+0

完成正是我想要的,謝謝!我是Cocoa的新手,但不是MVC。不過,作爲Java Web開發人員,我幾乎總是忘記「C」中的控制器可以相互交互! – bpapa 2008-10-28 20:39:21

1

我剛碰到同樣的問題。它絕對看起來如果你把一個UIViewController嵌入到NavigationController中,那麼當你從這個UIViewController中以模態方式呈現另一個UIViewController時,演示者認爲演示者是NavigationController。換句話說,parentViewController是不正確的。

我敢打賭,這是一個錯誤:要麼,或文件似乎不完整。我會詢問。

1

剛剛遇到同樣的問題。我相信這是一個錯誤。我的場景如下: 按此順序包含A,B和C視圖控制器的導航層次結構。在C上有一個按鈕可以打開一個名爲D的模態視圖控制器。一旦D出現,導航控制器就會從其層次結構中刪除C,這是一種可怕的行爲。一旦D被解散,導航控制器實例化新的C類型視圖控制器並將其推入其層次結構中以恢復原始的一個。可怕。我的解決辦法是黑客導航層次這種方式(一個非常糟糕的解決方案,但效果很好用2維數組,你可以實現堆疊模態):

- (void)presentModalViewController:(UIViewController *)c { 
    [self.navigationHierarchy removeAllObjects]; 
    [self.navigationHierarchy addObjectsFromArray:[navigation viewControllers]]; 
    [navigation setViewControllers:[NSArray array] animated:YES]; 
    [navigation presentModalViewController:c animated:YES]; 
} 

- (void)dismissModalViewController { 
    [navigation dismissModalViewControllerAnimated:YES]; 
    [navigation setViewControllers:[NSArray arrayWithArray:self.navigationHierarchy] animated:YES]; 
} 

這兩種方法的定義,我保持主導航hiererchy:應用程序代表。導航和navigationhierarchy的定義是這樣的:

NSMutableArray *navigationHierarchy; 
UINavigationController *navigation;