2010-09-23 61 views
0

我想使用模態視圖(UIViewController)作爲「正常」視圖,該視圖可以在導航控制器堆棧上推送。通常情況下,一個模式的看法,提出這樣的:使用模態視圖作爲「正常」視圖

LoginViewController *myView = [[MyViewController alloc] init]; 
UINavigationController *navController = [[UINavigationController alloc] initWithRootViewController:myView]; 
[self.navigationController presentModalViewController:navController animated:YES]; 
[myView release]; 
myView = nil; 
[navController release]; 
navController = nil; 

但我想要做這樣的事情:

[[self navigationController] pushViewController:myView animated:YES]; 

的問題是,我的模式的看法有權利和左按鈕。所以我將不得不檢查視圖如何加載並以另一種方式呈現按鈕。這背後的想法是有後退按鈕。所以我可以多次使用相同的模態視圖。

編輯:

@petert:

現在我也跟着你的榜樣。我的問題是,我正在使用UINavigationBar模式視圖。爲了得到這個UINavigationBar我創建了一個導航控制器。我正在使用導航欄,因爲我的按鈕在裏面。因此,檢查parentViewControllerUINavigationController類型是否適用於我。我總是得到一種模態觀點。下面是我該怎麼做:

// load modal view 
MyViewController *myView = [[MyViewController alloc] init]; 
UINavigationController *navController = [[UINavigationController alloc] initWithRootViewController:myView]; 
[[self navigationController] presentModalViewController:navController animated:YES]; 
[navController release]; 
navController = nil; 
[myView release]; 
myView = nil; 


// load as normal view 
MyViewController *myView = [[MyViewController alloc] init]; 
[[self navigationController] pushViewController:myView animated:YES]; 

回答

2

在這個StackOverflow的好技巧answer

我更喜歡使用UIViewController的屬性:在視圖控制器的子類

@property(nonatomic, readonly) UIViewController *parentViewController 

看看控制器的parentViewController屬性的值。如果它是UINavigationController的實例,那麼你在導航堆棧中。如果以模態方式顯示,它將成爲最後一個視圖控制器的一個實例。

所以在-viewDidLoad例如:

- (void)viewDidLoad 
{ 
    if ([self.parentViewController isKindOfClass:[UINavigationController class]]) 
    { 
     // navigation controller 
     self.title = @"..."; 
    } 
    else 
    { 
     // modal 
     self.title = @"Modal"; 

     // add cancel and done buttons now... 
    } 
} 

或者,一個非常簡單的解決辦法是自定義init方法您MyViewController類編碼您的視圖控制器意圖。

添加以下到MyViewController頭:

@interface MyViewController : UIViewController 
{ 
    BOOL modal; 
} 

- (id)initForModal:(BOOL)isModal; 

@end 

現在在實現文件:

@interface MyViewController() 
@property (nonatomic) BOOL modal; 
@end 

@implementation MyViewController 

@synthesize modal; 

- (id)initForModal:(BOOL)isModal; 
{ 
    if (self = [super initWithNibName:@"MyViewController" bundle:nil]) 
    { 
     self.modal = isModal; 
    } 

    return self; 
} 

- (void)viewDidLoad 
{ 
    [super viewDidLoad]; 

    if (self.modal) 
    { 
     // add cancel and done buttons … 
    } 
    else 
    { 
     // assuming we're presented from a navigation view … 
    } 
} 

我們使用這個模式方式:

// load modal view 
MyViewController *myView = [[MyViewController alloc] initForModal:YES]; 

或者沒有模態:

// load as normal view 
MyViewController *myView = [[MyViewController alloc] initForModal:NO]; 

我假設你是從NIB創建視圖控制器,但一如既往地看到View Controller Progamming Guide for iOS,尤其是標題爲「定義自定義視圖控制器類」的部分。

+0

感謝您提供的示例代碼。我認爲它會運行良好,但我使用'UINavigationController'來呈現我的模態視圖。爲什麼我這樣做是在我編輯的問題中解釋的。也許你可以提供一個解決方案。 – testing 2010-09-26 12:24:18

+0

您的支持太棒了!這個解決方案非常簡單,運行良好。現在我的理解有些問題:1)爲什麼要在實現文件中做一個新的接口聲明? 2)'initForModal'中的'if'調用super構造函數,如果成功則返回對象('ViewController'),否則返回nil。它是否正確?在'if'語句中,如果對象不是零,則只設置一個選項。 3)我需要這裏的屬性,因爲變量在方法邊界之上使用? – testing 2010-09-27 15:43:55

+0

很高興有幫助 - 1)它隱藏了模態屬性,因爲它不能在這個類的實現之外使用; 2)絕對是,它是init方法的通用obj-c風格; 3)我使用了一個屬性來簡化事情,我認爲你的問題的答案是肯定的?如果有幫助,請記得投票答覆,謝謝。 – petert 2010-09-27 15:59:29

0

澄清:myView不是模態的。你只是把它作爲一個模態展現出來。

如果你只是將它推入UINavigationController層次結構,它將表現得像一個「正常」的。

您不能將相同的視圖控制器多次推入導航堆棧。就一次。

也看到了如何自定義視圖:

SO modal question

+0

好的,我將它作爲模態視圖呈現。你有一個「真實」模態視圖的例子嗎?我不想將它同時推入堆棧。你什麼意思只有一次?我可以把它作爲普通的視圖在堆棧上,但後來不是模態視圖? – testing 2010-09-24 13:55:53