I'm not sure how to do this. So I originally had a ViewController that had one .xib, with one main view. I present it like this:
DogViewController *dvc = [[DogViewController alloc] initWithNibName:#"DogViewController" bundle:nil];
dvc.modalPresentationStyle = UIModalPresentationFormSheet;
dvc.modalTransitionStyle = UIModalTransitionStyleFlipHorizontal;
[self presentModalViewController:dvc animated:YES];
[dvc release];
So that works fine. However now from a button press in the DogViewController.xib, I want to dismiss the current form sheet, and show another form sheet with some additional questions before proceeding. So I started by adding another view to in my original .xib of DogViewController, then got stuck in the logic of how to dismiss the first one, and show the second one. I'm assuming I need some outlet to the new view in the same .xib, but from there I'm lost. Thanks.
The way to do this would be to set it up with a UINavigationController as Mathiew mentions. However, if you really want to transition between two views on one view controller, you can refer to this sample code from Apple:
http://developer.apple.com/library/ios/#samplecode/ViewTransitions/Introduction/Intro.html
The code uses ImageViews to demonstrate the effect but I don't see why you can't use views instead :)
You can add a view within the other view in front of all of the other objects and just use its hidden property to control whether it's shown or not.
Why don't you use a navigation controller in your modal view, create another xib and do a [self.navigationController pushViewController:secondViewController animated:YES];
If you have a good reason, you can set a second view outlet secondView and use code like
UIView* superview = [self.view superview];
[self.view removeFromSuperView];
[superview addSubview:self.secondView];
Very simple solution is to hold reference to MainViewController and call methods on it that swap between two view controllers.
Like this:
#implementation MainViewController
- (void)showDogViewController {
[self dismissModalViewControllerAnimated:YES];
DogViewController *dvc = [[DogViewController alloc] initWithNibName:#"DogViewController" bundle:nil];
dvc.modalPresentationStyle = UIModalPresentationFormSheet;
dvc.modalTransitionStyle = UIModalTransitionStyleFlipHorizontal;
dvc.mainViewController = self;
[self presentModalViewController:dvc animated:YES];
[dvc release];
}
- (void)showCatViewController {
[self dismissModalViewControllerAnimated:YES];
CatViewController *cvc = [[CatViewController alloc] initWithNibName:#"CatViewController" bundle:nil];
cvc.modalPresentationStyle = UIModalPresentationFormSheet;
cvc.modalTransitionStyle = UIModalTransitionStyleFlipHorizontal;
cvc.mainViewController = self;
[self presentModalViewController:cvc animated:YES];
[dvc release];
}
}
#end
#implementation DogViewController
- (void)showCatViewController {
[mainViewController showCatViewController]
}
#end
#implementation CatViewController
- (void)showDogViewController {
[mainViewController showDogViewController]
}
#end
Related
When I push cancel button in the third view, I want to go back to the first view directly.
I also want to remove the second view.
How can I do that?
This is the code.
// this part is in the first view.
self.second = [SecondController alloc] init];
[self.view addSubview:second.view];
// this part is in the second view.
ThirdController *thirdController = [[ThirdController alloc] initWithStyle:UITableViewStyleGrouped];
self.navigationController = [UINavigationController alloc] initWithRootViewController:thirdController];
[self.view addSubview:navigationController.view];
// this part is in the third view.
- (void)cancel {
[self.view removeFromSuperview]; // this only goes to the second view.
}
EDIT:
Can I use popToViewController in called contoller? My app crashes.
I thought popToViewController can be used only in calling controller.
And popToViewController is used when it was pushed.
I did add not push.
[self.navigationController popToViewController:[[self.navigationController viewControllers] objectAtIndex:0] animated:YES];
popToViewController:animated: is a UINavigationController method that you use when popping view controllers off the navigation controller stack. It doesn't fit for this scenario.
This user is adding subviews, not pushing them on a navigation controller stack.
As a note, it appears as a matter of design you should be using a navigation controller with the first view as the root controller, then the second pushed on the stack, and the third pushed on the stack. Then all you have to do is [self.navigationController popToRootViewControllerAnimated:YES].
I think this will work if you want to keep your current architecture:
// this part is in the third view.
- (void)cancel {
// remove the second view (self.view.superview) from the first view
[self.view.superview removeFromSuperView];
// can't recall, possibly you still need to remove the third view, but i think removing the superview will do it.
// [self.view removeFromSuperView];
}
If you prefer to try the UINavigationController route, then the easiest path is to create a new project in Xcode and select the type for a Navigation-Based Application or a Master-Detail Application. This will create a UINavigationController in a nib and add it to your window. You can then set the root view controller in Interface Builder to your FirstViewController class.
If you prefer to create the UINavigationController in code, then that is also possible. I show that below, along with the rest of the code you need, regardless of whether you create your UINavigationController in a nib in IB or in code.
I also recommend reading the View Controller Programming Guide for iOS.
In your app delegate or some other code:
-(void)application:(UIApplication*)application didFinishLaunchingWithOptions:(NSDictionary*)launchOptions [
// I would recommend setting up the UINavigationController and FirstViewController as IBOutlets in your nib, but it can be done in code.
FirstViewController* fvc = [[FirstViewController alloc] initWithNibName:#"FirstView" bundle:nil];
UINavigationController* navController = [[UINavigationController alloc] initWithRootViewController:fvc];
[window addSubView:navController.view];
[window makeKeyAndVisible];
[fvc release];
[navController release];
}
In the first view controller:
SecondViewController* svc = [[SecondViewController alloc] initWithNibName:#"SecondView" bundle:nil];
[self.navigationController pushViewController:svc animated:YES];
[svc release];
In the second view controller:
ThirdViewController* tvc = [[ThirdViewController alloc] initWithNibName:#"ThirdView" bundle:nil];
[self.navigationController pushViewController:tvc animated:YES];
[tvc release];
In the third view controller:
-(void)cancel {
// returns to the first view controller
[self.navigationController popToRootViewControllerAnimated:YES];
}
Use
- (NSArray *)popToViewController:(UIViewController *)viewController animated:(BOOL)animated
to go back to a specific view controller.
Try this:
[self.navigationController popToViewController:[self.navigationController.viewControllers objectAtIndex:1] animated:YES];
This will pop to the view at index 1. Hope that Helps!
// this part is in the third view.
- (void)cancel {
self.first = [SecondController alloc] init];
[self.view addSubview:second.view];
}
And I think if you have you don't need to be worried about removing beneath view, later these will removed.
Okay, working on a transition between a view with a tabbar and another view which is to be an information/about view. I have the code to transition from the view with tabbar and to transition back to previous view, but during the transition back I lose the tabbar at the bottom. Not sure exactly how to approach this with the tabbar in the MainWindow.xib
E.g.:
(IBAction)backButtonPressed:(id)sender
{
TablesViewController *tvc = [[TablesViewController alloc] initWithNibName:#"TablesView" bundle:nil];
tvc.modalTransitionStyle = UIModalTransitionStyleCrossDissolve;
[self presentModalViewController:tvc animated:YES];
[tvc release];
}
Thanks,
np
Try presenting the modal transition from the containing instance of UITabBarController and not the UIViewController the action was triggered from.
- (IBAction)backButtonPressed:(id)sender
{
TablesViewController *tvc = [[TablesViewController alloc] initWithNibName:#"TablesView" bundle:nil;
tvc.modalTransitionStyle = UIModalTransitionStyleCrossDissolve;
[self.tabBarController presentModalViewController:tvc animated:YES];
[tvc release];
}
I had the exact same problem, did a ugly solution:
- (IBAction)backButtonPressed:(id)sender {
[self.navigationController dismissModalViewControllerAnimated:YES];
}
I need help figuring out how to change out the view in my application. I have a wonderfully working view that I have finished and now I'd like to be able to switch the view to a brand new, blank white screen to display.
I have these files:
HelloAppDelegate.h,
HelloAppDelegate.m,
HelloViewController.h, and
HelloViewController.m
Then, I added a new View Controller so now I have two more files:
SecondViewController.h and
SecondViewController.m
In my first view (HelloViewController), I have a button. When the user presses this button, I'd like SecondViewController to show up. So, in my HelloViewController.m, I have an action method
-(IBAction)switchToSecondView:(id)sender {
}
In this method, how can I go about initializing my second view and displaying it?
Thanks in advance!
If you want to do something like flipping view, making it modal and then returning back to the main view do following:
Define a delegate to indicate that secondary view finished its work
#protocol FlipsideViewControllerDelegate
- (void)flipsideViewControllerDidFinish;
#end
In main view do following:
- (void)flipsideViewControllerDidFinish {
[self dismissModalViewControllerAnimated:YES];
}
- (IBAction)showInfo {
FlipsideViewController *controller = [[FlipsideViewController alloc] initWithNibName:#"FlipsideView" bundle:nil];
controller.delegate = self;
controller.modalTransitionStyle = UIModalTransitionStyleFlipHorizontal;
[self presentModalViewController:controller animated:YES];
[controller release];
}
In secondary view do following:
- (IBAction)done {
[self.delegate flipsideViewControllerDidFinish];
}
here's my code:
ViewController *vc = [[ViewController alloc] initWithNibName:#"TableView" bundle:nil];
[self.navigationController presentModalViewController:vc animated:YES];
//[self setView:[vc view]];
If I call it, nothing happens. However, if I change it to:
ViewController *vc = [[ViewController alloc] initWithNibName:#"TableView" bundle:nil];
//[self.navigationController presentModalViewController:vc animated:YES];
[self setView:[vc view]];
The view appears just fine (without the transition, of course).
What am I doing wrong? Is there anything special you have to take care of when initializing the view controller? I tried to copy as much as possible from Apple's examples, but I can't get this to work...
Thanks for any input!
-- Ry
You can only present modal view controllers from controllers that have already been shown onscreen (usually through a UINavigationController or UITabBarController). Try creating a UINavigationController, pushing a viewController to it, and then presenting your modal controller. There's a starter project in Xcode that shows how to create a UINavigationController-based flow if you're unfamiliar with it.
One other thing to note: if you haven't pushed the view controller onto a UINavigationController, the .navigationController property will be nil, and messaging it will have no effect.
I encountered the same problem while attempting to show a modal view over another modal view. Ben's answer is correct, and can be implemented like so:
#interface FirstView: UIViewController {
UIViewController *firstView;
}
- (IBAction)showOptionsView:(id)sender;
#end
In the main view class:
- (void)viewDidLoad {
[super viewDidLoad];
firstView = [[UIViewController alloc]init];
[firstView setView:self.view];
[firstView setModalTransitionStyle:UIModalTransitionStyleCoverVertical];
}
- (IBAction)showOptionsView:(id)sender {
OptionsView *optView = [[OptionsView alloc]initWithNibName:#"OptionsView" bundle:nil];
if(firstView != nil) {
[firstView presentModalViewController:optView animated:YES];
[optView release];
}
I have 2 XIBs with their corresponding View Controllers. Will call them MainViewController and AboutViewController. The names of the XIBs are exactly the same as the names of the ViewControllers. Upon a button click in the MainViewController, I want to show the AboutViewController.
I have code like this in the MainViewController:
- (IBAction) infoButtonAction:(id)sender {
AboutViewController *aboutViewController = [[AboutViewController alloc] init];
[[self navigationController] pushViewController:aboutViewController animated:YES];
}
But nothing happens, the AboutViewController does not show up. I also tried this line:
AboutViewController *aboutViewController = [[AboutViewController alloc] initWithNibName:#"AboutViewController" bundle:nil];
But to no avail. What am I missing?
Examine your AboutViewController.xib in Interface Builder and ensure that the File Owner is set to AboutViewController in the class inspector. Also ensure that the view property of the File Owner is wired into the View in the xib. Finally, the code to display it should read:
- (IBAction) infoButtonAction:(id)sender {
AboutViewController *aboutViewController = [[AboutViewController alloc] initWithNibName:#"AboutViewController" bundle:nil];
[[self navigationController] pushViewController:aboutViewController animated:YES];
[aboutViewController release];
}
Also, you should check that this is non-nil inside that same method:
UINavigationController * nc = self.navigationController;
do you get an error? Did you check that the button is correctly wired in IB?
did you try using a modal view controller?