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?
Related
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
I have a class called CataloguesEtTarifsPDFViewController which displays a tableView.
Now, inside this class I wanna create a UINavigationController and set the root of the UINavigationController this class:
Here is what I did:
CataloguesEtTarifsPDFViewController.h
UINavigationController *navigationController;
in the implementation file
CataloguesEtTarifsPDFViewController.m
- (void)viewDidLoad
{
CataloguesEtTarifsPDFViewController *catalog =[[CataloguesEtTarifsPDFViewController alloc] init];
loadingView.hidden=YES;
navigationController = [[UINavigationController alloc] initWithRootViewController:catalog];
}
When I click on the table cell I do this:
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
WebViewController *webViewController = [[WebViewController alloc] init];
[self.navigationController pushViewController:webViewController animated:YES];
[navigationController release];
}
But when I run and click on the tableView nothing happens...not view is showed up!!!Where am I going wrong?
IMPORTANT: I don't have a delegate file.Only CataloguesEtTarifsPDFViewController.h CataloguesEtTarifsPDFViewController.m and CataloguesEtTarifsPDFViewController.xib.
EDIT:
- (IBAction)showViewCataloguesEtTarifsPDF:(id)sender{
// Remove view to middleView
[mainMenuViewController removeViewsToMiddleView];
// create view controller
cataloguesEtTarifsPDFViewController = [[CataloguesEtTarifsPDFViewController alloc] init];
cataloguesEtTarifsPDFViewController.mainMenuViewController = mainMenuViewController;
// hide/show header button
[mainMenuViewController.headerViewController showMainMenuButton];
// highlight footer tabbar button
[mainMenuViewController.footerViewController.footerTabBar setSelectedItem:mainMenuViewController.footerViewController.footerTabBarItemMyAudi];
UINavigationController* navigationController = [[UINavigationController alloc] initWithRootViewController:cataloguesEtTarifsPDFViewController];
[self presentModalViewController:navigationController animated:YES];
}
You should probably read this: http://www.iosdevnotes.com/2011/03/uinavigationcontroller-tutorial/
Or this: http://developer.apple.com/library/ios/#featuredarticles/ViewControllerPGforiPhoneOS/Introduction/Introduction.html#//apple_ref/doc/uid/TP40007457-CH1-SW1
Or watch this: http://peepcode.com/products/iphone-view-controllers-part-i
That'll give you the basics and you'll be well equipped to answer your question and fix your code :)
PS: You don't have to explicitly create and set a UINavigationController in your view controller. If the view controller is embedded within a navigation controller, the navigationController property of your view controller instance will automatically find it and return it.
What you're doing in viewDidLoad is wrong.
Wherever you are showing the CataloguesEtTarifsPDFViewController, you should wrap it in a UINavigationController there and show the UINavigationController instead.
This will make sure the navigationController property of UIViewController will be set.
In your tableView:didSelectRowAtIndexPath: method you should release the webViewController variable instead of the navigationController property.
The other day I asked about using a UINavigationController as a child of a UIViewController. I got that working via the answer. Now what I'm trying to do is push a controller onto the nav stack. When a table cell is touched, I do the following:
- (void) showSetup {
NSLog(#"Showing Setup");
SetupViewController *controller = [[SetupViewController alloc]initWithNibName:#"SetupViewController" bundle:nil];
self.setupViewController = controller;
self.setupViewController.title = #"Setup";
[self.navigationController pushViewController:self.setupViewController animated:YES];
[controller release];
}
I can see the log statement in my console, but the view never changes. Am I missing something?
Hmmm, well it's a bit tricky without knowing the details of your implementation -- I assumed that you implemented your navigation controller as in the linked article. Also although you give no details it sounds like you've added a table view controller somewhere along the line, so I made the UIViewController conform to the UITableView protocols to handle everything in one place:
#interface SOViewController : UIViewController<UITableViewDelegate,UITableViewDataSource > {
UINavigationController* navController;
}
- (IBAction) pushMe:(id)sender;
#end
I dropped a button on the SOViewController's view in IB and wired the pushMe: action to it. I also created another UIViewController-based class called JunkController and dropped a "Junk" label on it's view in IB -- that's all I did in IB. In the SOViewController's viewDidLoad:
navController = [[[UINavigationController alloc] init] retain];
navController.navigationBar.barStyle = UIBarStyleBlackOpaque;
navController.toolbarHidden = YES;
UITableViewController* tvController = [[UITableViewController alloc] init];
UITableView* tv = [[UITableView alloc] init];
tvController.tableView = tv;
tv.delegate = self;
tv.dataSource = self;
[navController setViewControllers:[NSArray arrayWithObject:tvController]];
In the pushMe: action implementation:
[self presentModalViewController:navController animated:YES];
Implemented the tableView delegate and datasource methods; for selection:
- (void) tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
NSLog(#"row selected");
JunkController* junk = [[JunkController alloc] initWithNibName:#"junkcontroller" bundle:nil];
[navController pushViewController:junk animated:YES];
[junk release];
}
This should yield an app that surfaces a screen with a "Push me" button. When that button is pressed you should get an animated modal navigation-based table view -- mine had one row in it that contained a label "select me". Touching this row should animate the junk controller into view.
There is no need to make setupViewController a declared property in this view controller. Also, I could be mistaken but I thought "controller" was a reserved name in Cocoa, I'd change that name. So make sure you have registered with the UITableViewDelegate and use - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath to hook into and push your new view controller as follows:
SetupViewController *detailViewController = [[SetupViewController alloc] initWithNibName:#"SetupViewController" bundle:nil];
detailViewController.title = #"Setup";
[self.navigationController pushViewController:detailViewController animated:YES];
[detailViewController release];
Goodluck!
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];
}
hello i am having same issue, i tried your solution but it didnt help me in my case..
i am not getting exception but view is not getting changed..
my piece of code is as below
printf("hi");
//Get the selected country
NSString *selectedCountry = [listOfItems objectAtIndex:indexPath.row];
//Initialize the detail view controller and display it.
DetailViewController *aSecondView = [[DetailViewController alloc] initWithNibName:#"DetailView" bundle:nil];
// aSecondView.selectedCountry = selectedCountry;
[self.navigationController pushViewController:aSecondView];
[aSecondView release];
aSecondView = nil;
printf("bye..");
both hi and bye gets printed but view doesnt change..
i have wasted 2 days around it ..
plz help me out..
Check the nib name.How did you created the nib file for the detail view?.It will be created by default as DetailViewController in your case.So change the initWithNibName.Why do you set the aSecondView=nil?
as kovpas said , that subclass your controller from UIViewController instead of UINavigationController ,you use presentModalViewController. for implementing navigation controller put this code in your delegate class
- (void)applicationDidFinishLaunching:(UIApplication *)application {
UINavigationController *nvcontrol =[[UINavigationController alloc] initWithRootViewController:viewController];
[window addSubview:nvcontrol.view];
[window makeKeyAndVisible];
}
Seems, that you subclass your controller from UIViewController instead of UINavigationController
Try to use
[self presentModalViewController:aSecondView animated:YES];
Dismiss it with
[self dismissModalViewControllerAnimated:YES];
in case if you un comment your commented code...one another problem that i found in your code... interchange these 2 lines...
aSecondView.selectedCountry = selectedCountry;
[self.navigationController pushViewController:aSecondView];
try Put it like this
[self.navigationController pushViewController:aSecondView];
aSecondView.selectedCountry = selectedCountry;
if you uncommnet the line it may create problem