In iOS 7 Apple introduced new transition when you push view controller on top of another view controller. The transition comes with nice animation and back gesture. The back button displays the title from previous view controller which is good for accessibility:
You know where you are by looking on a title. You know that title is not intractable because it has different to tint color, usually, black.
You know where you come from with the back button label.
Unfortunately, our design require to remove navigation bar label because sometimes it is too long and it move navigation bar title to the right a little.
Here is how our design should look and work during the transition:
We removed the title from the first view controller in viewDidLoad of the first view controller (the one which is behind):
- (void)viewDidLoad {
[super viewDidLoad];
self.navigationItem.backBarButtonItem = [[UIBarButtonItem alloc] initWithTitle:#"" style:UIBarButtonItemStylePlain target:nil action:nil];
Now our transition has status bar background color problem:
Status bar change background color to grey during transition. Both view controllers have white status bar background.
Pushing second view controller:
SecondVC *svc = [sb instantiateInitialViewController];
[self.navigationController svc animated:YES];`
The solution is to remove this line from our code:
[[UINavigationBar appearance] setBackgroundColor:Colour_White];
In first ViewController -
-(void)viewWillAppear:(BOOL)animated{
[super viewWillAppear:YES];
UIBarButtonItem *btn=[[UIBarButtonItem alloc]initWithTitle:#"" style:UIBarButtonItemStylePlain target:self action:nil];
self.navigationItem.backBarButtonItem=btn;
}
Related
Similar to the issue described here, with the exception that my TabBar is actually showing the BackButton on my NavigationBar is not. In the question I provided a link to the answer that solved the problem was that there was a NavigationController within a NavigationController, I do not have that so this is a different issue.
The basic flow of my storyboard is Login (UIView) - TabBar (UITabBarController) - NavigationController (UINavigationController) - Actual visible screen (UITableViewController) - New TableView where the issue occurs (UITableViewController).
On the new actual visible screen or the TableView the NavigationBar at the top shows just fine and I can click in the general area that the BackBarButton should be and it will go back, but no BackBarButton item is visible.
I tried changing the color, allocating it in the previous ViewController, making sure it was visible, etc. And none of them have shown the Back Button. It seems to be there but it is not shown.
Any ideas? From the other question that is similar to my issue this seems to be a iOS 9 specific thing.
EDIT from looking at the Debug View Hierarchy I can tell that the back button is in fact there but it just has no label or back arrow on it. How can I make the back label visible?
EDIT 2
Here is the viewDidLoad method of the view controller where the back button should appear.
- (void)viewDidLoad {
[super viewDidLoad];
self.navigationItem.backBarButtonItem = [[UIBarButtonItem alloc] initWithTitle:#" " style:UIBarButtonItemStylePlain target:nil action:nil];
[self.navigationItem.backBarButtonItem setTintColor:[UIColor whiteColor]];
// Other unimportant stuff
}
The way I am segueing to this view controller is through the storyboard with a Push segue. Code is below.
- (void)segueToUser: (UIButton*)button {
long row = button.tag;
PFObject *PFQuote = [_recent quoteAtIndex:(row-1)/2];
PFUser *u = [PFQuote objectForKey:#"creator"];
_send = u;
[self performSegueWithIdentifier:#"showUser" sender:self];
}
Here is my prepareForSegue in the same file as the segueToUser
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
if ([segue.identifier isEqualToString:#"showUser"]) {
BRETTFUserTableViewController *bfutvc = [segue destinationViewController];
self.navigationItem.backBarButtonItem = [[UIBarButtonItem alloc] initWithTitle:#" " style:UIBarButtonItemStylePlain target:nil action:nil];
bfutvc.us = _send;
}
}
Here is a picture of a section of my storyboard.
The first view is a tabView
The second view is a navView
The third view is a tableView
The fourth view is a tableView
Since no one has seemed to have found a solution I will provide additional information. From my digging deeper into the Debug View Hierarchy I have found some more information regarding the backButton. I can see that the back arrow is intact there and there is a NSString next to it that seems to be nil, I do not know why it is nil but that is what I found. Here are additional pictures of what I have found.
In your
(void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
you have Write a code line
self.navigationItem.backBarButtonItem = [[UIBarButtonItem alloc] initWithTitle:#" " style:UIBarButtonItemStylePlain target:nil action:nil];
In Above line you have set title " " Empty String.
Instead of empty string use the title which you want to show on back-button item. fr ex:
self.navigationItem.backBarButtonItem = [[UIBarButtonItem alloc] initWithTitle:#"Back" style:UIBarButtonItemStylePlain target:nil action:nil];
Check it might that help.
Adding a image of storyboard, how i have embedded the view controller in navigation controller.
or in case if you have put navigation appearance code anywhere in your app then also post that code.
In your viewDidLoad and prepareForSegue methods you have this :
self.navigationItem.backBarButtonItem = [[UIBarButtonItem alloc] initWithTitle:#" " style:UIBarButtonItemStylePlain target:nil action:nil];
Which replace the default back button of the navigation controller by a button without a label.
You should simply remove these 2 lines to have the default back button.
I have finally solved the issue. To accomplish this I had to go into the navigation bar for the first tableViewController and set the Back Button title to Back and then set the tint color (as it defaulted to clear) and now it works.
Following the examples of the many duplicates for this questions, I can't seem to get it right.
I have a UINavigationViewController that has a LoginViewController as the rootViewController. Here I got a button with a segue (push) to a LoginInfoViewController.
In LoginInfoViewController.m:
- (void)viewDidLoad
{
[super viewDidLoad];
//null
NSLog(#"%#", self.navigationItem.backBarButtonItem);
UIBarButtonItem *backButton = [[UIBarButtonItem alloc] initWithTitle:#"Test"
style:UIBarButtonItemStyleDone
target:nil
action:nil];
self.navigationItem.backBarButtonItem = backButton;
//not null, still the back button says: "Back"
NSLog(#"%#", self.navigationItem.backBarButtonItem);
}
You will need to set the backBarButtonItem of the controller you are going back to, not the controller you pushed. Move your code to the LoginViewController viewDidLoad method.
The navigation controller derives the back button for the navigation bar from the backBarButtonItem of the preceding controller in the stack. If the item is nil, it will use the value in the title property of same. If the title is too long to fit, the navigation bar may substitute the string "Back" in place of the title.
If your controller has a custom left bar button item, the navigation bar will ignore the backButtonItem property and title presenting the custom button instead.
Set the title of the back button on the view BEFORE. So, if you segue from LoginViewController, you set the back button title on the item before you segue to LoginInfoViewController
Example:
In the viewDidLoad method on LoginViewController:
UIBarButtonItem *newBackButton = [[UIBarButtonItem alloc] initWithTitle: #"Go back" style: UIBarButtonItemStyleBordered target: nil action: nil];
[[self navigationItem] setBackBarButtonItem: newBackButton];
This means you're setting the button on the LoginViewController, not on the LoginInfoViewController.
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 am trying to add a bar button to my iOS app and can't get it to show up. I can see the bar in the Navigation Item's view hierarchy by setting a breakpoint. If it helps, I chose 'Embed Navigation Controller'. Any idea what's going on?
UIBarButtonItem *item = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemAction target:self action:#selector(choosePreferredTerm:)];
[self.navItem setRightBarButtonItem:item animated:YES];
Here is the connection in IB
This is what the embedded Navigation Controller looks like:
This is what it looks like on the sim:
Try this rather than using custom outlet "navItem" also insure your application has a navigation controller in place
self.navigationItem.rightBarButtonItem = barButton;
My app layout is as follows -
the rootViewController is a tabViewController with 3 tabs each having a UINavigationController as their rootViewController. Within one of these tabs I am pushing upon cell selection to another tabController which now has two tabs. What I am trying to do is set the rightBarButtonItem on each of these two tab's viewControllers... in the viewDidLoad method of both of these I am doing:
self.navigationItem.rightBarButtonItem = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemEdit target:self action:#selector(selectionChanged:)];
however this is doing absolutely nothing! I thought from the apple documentations that you could set the navigationItem's rightBarButtonItem from anywhere within your navigation controllers view hierarchy but that doesn't seem to be the case here. Any idea what - if anything - I am doing wrong?
The solution to this is to instead of simply setting the rightBarButtonItem on self.navigationItem we need to set it on the parent tabBarController like so :
self.tabBarController.navigationItem.rightBarButtonItem = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemEdit target:self action:#selector(selectionChanged:)];