I want to use a modal view (UIViewController
) as a "normal" view, which can be pushed on the navigation controller stack. Normally, a modal view is presented like this:
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;
But I want to do something like this:
[[self navigationController] pushViewController:myView animated:YES];
The problem is that my modal view has a right and a left button. So I would have to check how the view is loaded and present the buttons in another way. The idea behind this is to have the back button. So I can use the same modal view a few times.
Edit:
@petert:
Now I followed your example. My issue is that I'm using a UINavigationBar
for the modal view. To get this UINavigationBar
I create a navigation controller. I'm usin开发者_如何学编程g the navigation bar because I have my buttons in it. So checking if parentViewController
is of type UINavigationController
does not work for me. I'm always getting a modal view. Here is how I do it:
// 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];
Good tips in this StackOverflow answer.
I prefer to use UIViewController's property:
@property(nonatomic, readonly) UIViewController *parentViewController
in a view controller's subclass:
Look at the value of the controller's
parentViewController
property. If it's an instance ofUINavigationController
, then you're in the navigation stack. If you're being displayed modally, it'll be an instance of your last view controller.
So in -viewDidLoad
for example:
- (void)viewDidLoad
{
if ([self.parentViewController isKindOfClass:[UINavigationController class]])
{
// navigation controller
self.title = @"...";
}
else
{
// modal
self.title = @"Modal";
// add cancel and done buttons now...
}
}
Or, a pretty simple solution would be to customize your init
method to your MyViewController
class to encode your intent for the view controller.
Add the following to the MyViewController
header:
@interface MyViewController : UIViewController
{
BOOL modal;
}
- (id)initForModal:(BOOL)isModal;
@end
Now in the implementation file:
@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 …
}
}
Now to use this modally:
// load modal view
MyViewController *myView = [[MyViewController alloc] initForModal:YES];
Or not modally:
// load as normal view
MyViewController *myView = [[MyViewController alloc] initForModal:NO];
I'm assuming you're creating the view controller(s) from NIBs, but as always see the View Controller Progamming Guide for iOS and especially the section titled "Defining a Custom View Controller Class".
For clarification: myView isn't modal. You just present it as a modal one.
If you just push it into a UINavigationController hierarchy it will behave like a "normal" one.
You can't push the same view controller onto the navigation stack several times. Just once.
Also see this for how to customize the view:
SO modal question
精彩评论