I have a navigation controller that has a hidden navigation bar on the first view, and then appears for all children views. Problem is, I can't seem to hide it again if you go back to the first view.
I created a back button (so I could rename it) in the first view's init:
self.navigationItem.backBarButtonItem = [[UIBarButtonItem alloc]
initWithTitle:#"Logout" style:nil target:self
action:#selector(hideNavigationBar:)];
But the method never gets called. Why?
In your first controller, in -(void)viewWillAppear, say:
[self.navigationController setNavigationBarHidden:YES animated:NO];
Related
I got a NavigationController(short for nv) and a ViewController(short for vc).
nv's RootViewController is vc.
My Goal
I just want to set the NavigationItem , I want the left bar button to be BACK button(customized).since this left button shared in all ViewControllers so I don't want to write the code in the ViewController , otherwise I have to write it many times. And I can't just subclass a ViewController, since I only need my customized left bar item in just a few ViewController.
So I try adding the generating button code in my nv , but i failed.
The result is , only the original vc got customized left bar button. other vc which is push on it all got the default one.
My Code
Here is my NavigationController's code:
- (void) viewWillAppear:(BOOL)animated{
[self createBackButton];
- (void) createBackButton{
UIViewController* vc = [self.viewControllers lastObject];
vc.navigationItem.leftBarButtonItem = nil;
vc.navigationItem.leftBarButtonItem =
[[UIBarButtonItem alloc]initWithTitle:#"Roll Back"
style:UIBarButtonItemStyleBordered
target:self
action:backButtonPressedSelector];
}
But if I put my createBackButton method in my ViewController , everything works just fine. But I also Have to write this method many times. Even the sentence like [self createBackButton]
it seems that viewWillAppear isn't a good time to call my createBackButtonMethod
My Question
In what order does the method below be called when I am pushing and hoping view controller , and where should I add my createBackButtonMethod in order to got some of the ViewController have the same left bar button without writing unnecessary code?
1、NavigationController's didload
2、NavigationController's willappear
3、ViewController(the one being pushed) 's didload
4、ViewController's willappear
Answer
The the method calling order is this:
1、vc's didload
2、nv's didload
3、nv's will appear
4、vc's will appear
and then when I continue to push vc, there are only
vc's didload and vc'didload being called repeatedly.
That's why I failed, because the nv's didload will only be called once here.
Instead of writing a common parent class, I think of the pretty solution below.
just do the adding things in the pushingViewController:method
So I override my pushViewController: method
- (void) pushViewController:(UIViewController *)viewController animated:(BOOL)animated{
viewController.navigationItem.leftBarButtonItem = nil;
viewController.navigationItem.leftBarButtonItem =
[[UIBarButtonItem alloc]initWithTitle:#"Roll Back"
style:UIBarButtonItemStyleBordered
target:self
action:backButtonPressedSelector];
}
try to make parent view controller and extend all your view controllers from it and add the needed code in there all the view controller will have it
hope i understand your question right and this answer help you with your problem good luck
--> Put all your code in viewcontroller's viewdidload or viewwillappear.
-->Viewdidload calls only once when you push the controller and viewwillappear will call every time in any case push, pop, present, dismiss etc.
--> First will call viewdidload and then will call view will appear.
Main screen in my app has 2 buttons. When click button 1, show ViewController1. When click button 2, show ViewController2. ViewController1 has 2 bar items. ViewController of each bar item has Back and Done button. Back is back to main menu, Done is used to hide keyboard. I want to control 2 these buttons.
I have 2 directions:
Add Navigation Controller at main screen. It has Back button. Button Done is implemented in ViewController of each bar item. In this case, button Done works not good when change tab bar. I loged and see that, first click in tab bar, it works correct, but click Item1->Item2->Item1, button Done in Item1 this time not correct, because it is still button Done in Item2 Controller.
How to fix in this case?
I hide Navigation Controller in main screen, implement Navigation Controller in Controller of each Tab Bar. In this case, button Done works good, but button Back can't move to main screen when click on it.
How to move to main screen in this case?
Code in AppDelegate.m:
UIViewController *cont = [[VCMainMenu alloc]initWithNibName:#"VCMainMenu" bundle:nil];
self.navController = [[UINavigationController alloc]initWithRootViewController:cont];
[self.window setRootViewController:navController];
Code in MainMenu.m, ViewDidLoad:
self.navigationItem.backBarButtonItem =
[[UIBarButtonItem alloc] initWithTitle:#"Back"
style:UIBarButtonItemStylePlain
target:nil
action:nil];
Code in MainMenu.m, buttonClick:
self.navigationController.navigationBarHidden = YES;
[self.tab setSelectedIndex:0];
[self.navigationController pushViewController:self.tab animated:YES];
Button Done in each class:
UIBarButtonItem *btnDone = [[UIBarButtonItem alloc]initWithBarButtonSystemItem:UIBarButtonSystemItemDone target:self action:#selector(btnDonePressed:)];
self.navigationController.topViewController.navigationItem.rightBarButtonItem = btnDone;
btnDone.enabled = TRUE;
btnDone.style = UIBarButtonSystemItemDone;
Thanks.
To hide the Keyboard you need to know which textView is firstResponder. You have to implement a dismisskeyboard method for each of your scenes.
Also, why are you coding all the navigation stuff? It would be much easier implementing them via storyboards and segues.
I hide Navigation Controller in main screen, implement Navigation
Controller in Controller of each Tab Bar. In this case, button Done
works good, but button Back can't move to main screen when click on
it. How to move to main screen in this case?
To do that, use
[self.navigationController popViewControllerAnimated:YES];
And as a sidenote #Marcal has a point, I think it might be better if you use storyboards and segues
I had two Table View Controllers and they are connected each other by "segues" in Storyboard. Then I've cut the "segues" and insert another controller. And connection now is not through "segues". To connect the views I'm using the code:
UIStoryboard *storyboard = self.storyboard;
OptionsViewController *options = [storyboard instantiateViewControllerWithIdentifier:#"OptionsViewController"]
[self.navigationController pushViewController:options animated:YES];
And now when I'm clicking a "Back" button in navigation bar my program crashes. How to fix it?
Console shows (After view loaded, before I've pressed the "Back" button.): "nested push animation can result in corrupted navigation bar"
"Finishing up a navigation transition in an unexpected state. Navigation Bar subview tree might get corrupted."
After I've pressed the "Back" button: "terminating with uncaught exception of type NSException"
Navigation Controller is the initial controller in my storyboard, but the Views are not connected each other.
FIXED: I've just set the "animated:NO" at the end of my code.
Check that to calling pushViewController before viewDidAppear is not safe. So you should create your code according to that.
Try modifying line to
[self.navigationController pushViewController:options animated:YES];
Update
If you don't care about normal back button, try below code.
- (void) viewDidLoad
{
// ADD BELOW CODE IN viewDidLoad ALONG WITH REST OF YOUR CODE
UIBarButtonItem *backButton = [[UIBarButtonItem alloc] initWithTitle:#”back”
style:UIBarButtonItemStyleBordered target:self action:#selector(backBarButton:)];
self.navigationItem.leftBarButtonItem = backButton;
}
- (void) backBarButton:(id)sender
{
[self.navigationController popViewControllerAnimated:YES];
}
You can play around with style to set your desired button style.
On iOS if you do not set the bar button item in the navigation stack manually, one is added for you with the previous controller's title and a back arrow. I want to keep the arrow only. e.g. if my previous controller's title was Hello, my current controller would have the leftbarbuttonitem as "< CustomTitle". Currently, I just have this:
UIBarButtonItem *goBackAndSaveButton = [[UIBarButtonItem alloc]initWithTitle:#"[insert arrow here]CustomTitle" style:UIBarButtonItemStylePlain target:self action:#selector(goBackAndSave)];
self.navigationItem.leftBarButtonItem = asdf;
Is there any way to control the title so I can set a custom title but still use the back arrow"
Rather than using a custom bar button item you could alternatively use one of the view controller life cycle methods like willMoveToParentViewController: as the trigger for your save. If you use willMoveToParentViewController: (when the parent is nil) you can save once when the view is removed. If you use viewWillDisappear: your save will run more frequently when pushing other views.
In the -viewDidLoad method of the controller you're pushing a new view controller from, use this code:
self.navigationItem.backBarButtonItem =
[[UIBarButtonItem alloc] initWithTitle:#"CustomTitle"
style:UIBarButtonItemStyleBordered
target:nil
action:nil];
Then when you push your new view controller, its back button will have your custom title.
I am navigating to Tab bar controller with 6 tabs from a RootViewController... I have created back button method in left navbar item which pops back all tab views to RootViewController... Problem arises when i try to pop the 5th or 5th tabview.. the back button doesnt work at all in MoreViewController, 5th tab and 6th tab...
Here's what works:
1)Pops back to RootView from 1 to 4 tabs
2)Pops back to RootView from More View (only first time it works)
3)Pops back to MoreView from 5th/6th View (only first time it works)
Here's what doesnt work:
1)Doesnt pop back to RootView from MoreView
What am i doing wrong?
- (void)viewDidLoad
{
...
self.tabBarController.navigationItem.leftBarButtonItem = [[UIBarButtonItem alloc] initWithTitle:#"Back" style:UIBarButtonSystemItemDone target:self action:#selector(goBack)];
...
}
Code for goBack method written in each tab
-(void)goBack{
[self.navigationController popToRootViewControllerAnimated:NO];
}
Try this.. May be it will help you
NSArray *viewContrlls=[[self navigationController] viewControllers];
for( int i=0;i<[ viewContrlls count];i++)
{
id obj=[viewContrlls objectAtIndex:i];
if([obj isKindOfClass:[rootController class]])
{
[[self navigationController] popToViewController:obj animated:YES];
return;
}
}
I figured out what was the problem and so i am going to answer my own question... I was writing popToRootViewController in each tab.. and so when i enter 5th tab and press back, it would come back to more view tab and forgets about the root view.. So i deleted popToRootViewController from each tab and wrote the code for popping the views at the time of Tab bar declaration in the Root View page... eg. Tab bar declaration, then setting tab bar nav button for going back which calls some method... and in that method i write popToRootViewController...