I have an application in which i am pushing a testviewcontroller from a viewcontroller.testviewcontroller has a back button and a yes button.when pressing the back button i am going back to the previous by using
[self.navigationController popViewControllerAnimated:YES];
when pressing the Yes button i am pushing another view controller using
GettingViewController *get =[[GettingViewController alloc] initWithNibName:#"GettingViewController" bundle:nil];
[self.navigationController pushViewController:get animated:NO];
this are all working fine.in the rewardsget when pressing a button i am poping back to testviewcontroller.using this `
for (TestViewController*vc in [self.navigationController viewControllers]) {
if ([vc isKindOfClass: [TestViewController class]]){
[[self navigationController] popToViewController:vc animated:YES];
}
}
`
but when i am pressing the back button in that view it needs to go to my new pushed view controller ie rewardsget.But when i am printing the view controllers it is not present in the stack.so it is again going back to the first pushed viewcontroller,not the latest.can anybody help me on this?
It sounds like you have multiple instances of TestViewController in your stack. To get to the correct one just pass a pointer to TestViewController to your GettingViewController, you may want to have a property:
#property (nonatomic, assign) TestViewController* testViewController;
When you're ready to go back to your TestViewController call [self.navigationController popToViewController: self.testViewController animated: YES];.
That said, it sounds like your navigation flow may need some more thought. On iOS a hub-and-spoke navigation flow is the most natural.
in your for loop you go through all the viewControllers but already pretend that these are TestViewController (TestViewController*vc ...). Of course the first one you are looking for isKindOfClass TestViewController then!
Try changing this to UIViewController*vc!
Related
I have a UIViewCOntroller, and my code is as follows.
TviewController *tviewController = [[TviewController alloc]init];
[self.navigationController pushViewController:tviewController animated:YES];
Now from TviewController i go to another viewCOntroller;
XviewController *xviewController = [[XviewController alloc]init];
[self.navigationController pushViewController:xviewController animated:YES];
in this XviewController there is a button, when i click that button i need to move BACK to the TviewController How do i do this programatically ?
note: I don't want to use pushViewController and push it further. I need to go back to the TviewController (as in clicking the back button twice)
Just
[self.navigationController popViewControllerAnimated:YES];
You should spend some time reading the guidelines about view controllers...
[self.navigationController popViewControllerAnimated:BOOL)]
[self.navigationController popToViewController:(UIViewController *) animated:(BOOL)];
[self.navigationController popToRootViewControllerAnimated:(BOOL)];
are methods to go back in hierarchy
there is 3 possible ways.
use popToRootViewControllerAnimated: -> to go back root view controller (first view controller)
use popViewControllerAnimated: -> to go backward 1. it's exact same way as back button.
use popToViewController:animated: -> to go back to UIViewController you want (as long as it's stack at back).
point 1 & 2 is pretty easy to implement and other answers lead you to there.
for point 3, here it is:
#class TviewController.h;
#interface XviewController : UIViewController
{
//this is XviewController.h
//you may use `#import` other than use `#class` but on some reason you can't, if you use`#import XviewController.h` in your TviewController class.
}
//XviewController.m
#import TviewController.h
#import XviewController.h
#implementation
-(IBAction) backTviewController
{
for ( UIViewController *viewController in self.navigationController.viewControllers )
if ( [viewController isMemberOfClass:[TviewController class]]{
[self.navigationController popToViewController:viewController animated:YES];
break;
}
}
I'm working on a view controller that can be presented modally or pushed into a navigation stack. I made it a UINavigationController subclass so that I get all the UIToolbar stuff for free. I can present it modally using:
[self presentModalViewController:myViewController animated:YES];
Problem is, UINavigationController doesn't allow pushing another UINavigationController into it (makes sense), so this crashes it:
[self.navigationController pushViewController:myViewController animated:YES];
Would there be a way to detect how myViewController is presented and automatically have it switch between UINavigationController and UIViewController accordingly so that I don't need 2 different classes?
In other words, myViewController would be able to detect how it's getting presented and pushing it would come down to something like:
[self.navigationController pushViewController:myViewController.topViewController animated:YES];
NOTE: Something like this would probably do, but it's getting too far away from the default UIViewController behaviors:
[myViewController pushIntoNavigationController:navController]; // only push myViewController.topViewController
[myViewController presentModallyInParentController:parentController]; // push the whole myViewController
In the myViewController subclass, create a method something like this:
- (void)presentFromViewController:(UIViewController *)presentingViewController
{
if ([[presentingViewController class] isEqual:[UINavigationController class]])
[presentingViewController pushViewController:self.topViewController animated:YES];
else
[presentingViewController presentModalViewController:self animated:YES];
}
Would this work or am I not understanding correctly?
I have uinavigation controller with a view controller named VC1,now i have a button in VC1 that when i click on him i go to view controller VC2,this is how i bring VC2 to screen :
VC2 *tmp = [[VC2 alloc]init];
[[self navigationController] pushViewController:tmp animated:YES];
[tmp release];
now when i click in VC2 on the back button of the navigation to return to VC1 its work but i put in VC2 viewDidDisappear and viewWillDisappear methods,and when i click on the back button this function won't called, any one have any idea?
You may call the view[..] methods manually from the UINavigationControllerDelegate callbacks, however the easiest way to ensure that the methods are called by the super implementation of the UINavigationController is just to call them manually once when the UINavigationController is allocated.
See my answer here: iPhone viewWillAppear not firing
So immediately after you have called navController = [[UINavigationController alloc] init.., make sure to call
[navController viewWillAppear:NO];
[navController viewDidAppear:NO];
[navController viewWillDisappear:NO];
[navController viewDidDisappear:NO];
This should ensure events are correctly forwarded to each view controller in the future.
If you want to call the viewWillDisappear/viewDidDisappear methods, your view controller has to do that manually before popping itself off the nav stack. Have a look at this
,you might get an idea how to do it.
I have a View application with a Single UIViewController. I then add a UITableViewController through the IB, and I am trying to display the UITableViewController through a button press in the UIViewController (my main view). My button press (IBAction) contains the following code through which I am trying to push my UITableViewController view and display it:
DataViewController *dataController = [[DataViewController alloc] initWithNibName: #"DataViewController" bundle:nil];
[self.navigationController pushViewController:dataController animated:YES];
[dataController release];
My DataViewController is not at all getting pushed into the stack and displayed,
Also I have checked that in the code above, self.navigationController=nil
Probably this is the source of the problem. If so, how to rectify it?
Please help.
UINavigationController *navCtrlr = [[UINavigationController alloc]initWithRootViewController:yourfirstviewController];
[self.window setRootViewController:navCtrlr];
navCtrlr.delegate = self;
navCtrlr.navigationBarHidden = YES;
Create navigation controller in appdelegate.m then you can navigate to any uiviewcontroller
You need to actually create a UINavigationController. The navigationController property tells you whether your DataViewController is currently in a UINavigationController's hierarchy; if not (as in this case), the navigationController property returns nil.
I have a problem where I can successfully push a new view controller from my root view controller (using the Navigation-based application using Core Data template), but the detail view, which is a separate xib file from the root view controller, doesn't display the back navigation button. I'm certain that I've done all of the proper connections in IB, and everything else is working as expected.
RootViewController.h
#class ItemsViewController;
#interface RootViewController : UITableViewController <NSFetchedResultsControllerDelegate> {
IBOutlet ItemsViewController *itemsVC;
}
#property (nonatomic, retain) IBOutlet ItemsViewController *itemsVC;
#end
RootViewController.m
#import "ItemsViewController.h"
#synthesize itemsVC;
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
// Pushes to ItemsViewController
ItemsViewController *itemsViewController = [[ItemsViewController alloc] initWithNibName:#"ItemsViewController" bundle:[NSBundle mainBundle]];
[self.navigationController pushViewController:itemsViewController animated:YES];
[itemsViewController release];
}
ItemsViewController is a UITableViewController subclass with its own xib, also named ItemsViewController. Again, it gets pushed from RootViewController, but the back button doesn't show up like this. I was under the impression that it was a "free" feature of using a navigation controller. As you might expect, this is a very frustrating roadblock and I would appreciate any help.
Does your ItemsViewController class set its title property in its viewDidLoad method?
You should call [tableView deselectRowAtIndexPath:indexPath animated:YES] as the last line of tableView:didSelectRowAtIndexPath: to conform to Apple's human interface guidelines.
Yeah, make sure you have a title on your RootViewController, if it doesn't no button will appear. To set a title programmatically;
self.navigationItem.title = #"Hello Der";
Some extra info for future readers: I ran into this problem while trying to re-populate a nav hierarchy on application load, so I was calling setViewControllers: from the app delegate's application:didFinishLaunchingWithOptions: method. And I was running into the same problem with the back button not showing up.
In my case, setting the root view controller's nav item title in its viewDidLoad did not work, presumably because the other views were loading first and seeing the root's title as null. Instead, I set the root view controller's nav item title in my application:didFinishLaunchingWithOptions: method right before I called setViewControllers:, and that fixed it.
This can also happen if you're a bonehead and mistakenly initialize the view as modal instead of pushing a view to the navigation controller.
oops: [self presentModalViewController:navController animated:YES];
meant: [self.navigationController pushViewController:controller animated:YES];
Try following snippet. It work for me!
[self.navigationController.navigationBar setBackgroundImage:[UIImage imageNamed:#"Image.png"] forBarMetrics:UIBarMetricsDefault];
[self.navigationController.navigationBar bringSubviewToFront:[self.navigationController.navigationItem backBarButtonItem]];