Where should this tab bar controller be embedded? - ios

The Initial View Controller of this project is a Navigation Controller. I want to show a Tab Bar Controller on a View Controller later in the view hierarchy after the user signs in.
When I embed a Tab Bar Controller on the View Controller I want it to be on, the navigationBar I have programmatically implemented gets overridden with a new navigationBar item that, when pressed, leads the user back to the log in page.
Here is the code for the navigationBar.
self.navigationController.navigationBar.tintColor = [UIColor whiteColor];
//Changes The Title Color
[self.navigationController.navigationBar setTitleTextAttributes:[NSDictionary dictionaryWithObject:[UIColor whiteColor] forKey:NSForegroundColorAttributeName]];
//Sets The Navigation Controller Font
[self.navigationController.navigationBar setTitleTextAttributes:
[NSDictionary dictionaryWithObjectsAndKeys:
[UIColor whiteColor], NSForegroundColorAttributeName,
[UIFont fontWithName:#"ArialMT" size:12.0], NSFontAttributeName,nil]];
[[UINavigationBar appearance] setBarTintColor:UIColorFromRGB(0x0080ff)];
self.navigationController.navigationBar.translucent = YES;
self.navigationItem.leftBarButtonItem = btnRefresh;
//
self.navigationItem.rightBarButtonItem = btnCompose;
Here is how the navigationBar is supposed to be implemented on the View Controller:
Here is what happens when a Tab Bar Controller in embedded in the View Controller that I want it to be on:
What is the correct way to show a Tab Bar Controller on this View Controller that will preserve the existing navigationBar? Apple's Documentation on Tab Bar Controllers seems extensive and it seems it should be implemented programmatically.

According to Apple docs TabBarController should not be pushed to UINavigationController. Instead you can just use UITabBar and UITabBarDelegate to get same effect. You can refer below link of documentation.
https://developer.apple.com/documentation/uikit/uinavigationcontroller/1621887-pushviewcontroller

Related

Buttons on navigation bar do not pick up window tint colour

Note, I've recently come back to this and it seems to have been fixed in more recent versions of the SDK, without me having to implement anything except the code in the question. Many thanks to all who answered.
I have an Objective-C app that runs on the iPad and displays a view controller with a modal presentation style of UIModalPresentationPageSheet:
UINavigationController *editorNavigationController = [[UINavigationController alloc] initWithRootViewController:editorViewController];
editorNavigationController.modalPresentationStyle = UIModalPresentationPageSheet;
[navigationController presentViewController:editorNavigationController animated:YES completion:nil];
When this view controller is displayed the buttons in the navigation bar are purple, which I assume has been picked up from the window's tint colour, which is what I want.
Later I need to display another view controller over the top, that fills the whole window:
UINavigationController *previewNavigationController = [[UINavigationController alloc]initWithRootViewController:myPreviewViewController];
[owningViewController presentViewController:previewNavigationController animated:YES completion:nil];
The problem I have is that when myPreviewController is displayed, the buttons in the navigation bar are grey. I've tried reinstating the colour on the new navigation controller:
previewNavigationController.navigationBar.tintColor = [UIColor colorWithRed:123/255.0 green:26/255.0 blue:69/255.0 alpha:1];
but without any joy.
How can I get the buttons to have the correct colour? Can I get the new navigation controller to pick up the window tint colour automatically, or do I have to set it explicitly? Is this something to do with presenting the second navigation controller over the top of one that uses UIModalPresentationPageSheet?
Any help much appreciated! Thanks,
Paul
You can set the navigationBar translucent and transparent.
In view Will Appear:
self.navigationController.navigationBar.translucent = NO;
Than create a UIView with frame size of navigationBar (CGRectMake(0,0,self.view.frame.size.height,22) and create buttons on it with color you need.
I know, thats a crutch but should work)
You can change the appearance of the UIBarButtonItem globally so all UINavigationControllers will share the same design:
[[UIBarButtonItem appearance] setTintColor:[UIColor purpleColor]];
[[UIBarButtonItem appearance] setTitleTextAttributes:[NSDictionary dictionaryWithObjectsAndKeys:
[UIFont fontWithName:#"fontName" size:16.0f],NSFontAttributeName,
nil] forState:UIControlStateNormal];
Additionally you could also change the [UINavigationBar appearance]:
//The setTintColor would tint the < Back button in the NavigationBar
[[UINavigationBar appearance] setTintColor:[UIColor greenColor]];
[[UINavigationBar appearance] setBarTintColor:[UIColor redColor]];
[[UINavigationBar appearance] setTitleTextAttributes:
#{NSForegroundColorAttributeName:[UIColor blueColor]}];
This code can be add it before presenting the UIViewControllers or simply in the AppDelegate.m.

How to change a custom NavigationItem title and background color?

Earlier I used a navigationcontroller with this code :
self.navigationItem.title = #"News";
Now I have the problem that I no longer needed the navigationcontroller as I am using a page controller for navigation. Now I added a navigationbar however it doesn't change the title with this code anymore.
Also how can I change the background color?
IN iOS 7 use write following code in didFinishLaunchingWithOptions
if ([[UINavigationBar class] respondsToSelector:#selector(appearance)])
{
[[UINavigationBar appearance] setBarTintColor:[UIColor colorWithRed: 4.0/255.0 green:173.0/255.0 blue:214.0/255.0 alpha:1.0f ]]; //// change background color of navigationBar
[[UINavigationBar appearance] setTintColor:[UIColor whiteColor]]; /// set backButton color of navigation bar
[[UINavigationBar appearance] setTitleTextAttributes:#{NSForegroundColorAttributeName : [UIColor whiteColor]}]; // set title color
[[UIBarButtonItem appearanceWhenContainedIn:[UINavigationBar class], nil] setTitleTextAttributes:[NSDictionary dictionaryWithObjectsAndKeys:[UIColor whiteColor], UITextAttributeTextColor,nil] forState:UIControlStateNormal]; /// set all barButton item color
self.navController.navigationBar.translucent = NO;// set translucent NO
}
Use as per your requirement.
So there is some magic happening when you use a navigation controller that you don't see and now that you've made the switch to justing using a navigation bar you lose that magic.
Navigation bars are responsible for managing and presenting UNavigationItems, and as such hold an array of them. A NavigationItem holds things like left and right buttons, and the title or titleView. When your navigation controller pushes a new controller, it creates a brand new UINavigation item then links it to your new view controller, and then pushes that onto navigation bars stack of nav items. That's why from within your view controller you set the title with self.navigationItem.title instead of referencing the navbar.
Basically you have to manage the bar and nav items yourself now. This should about do it for you:
_navBar = [[UINavigationBar alloc] initWithFrame:CGRectMake(0, yOffset, CGRectGetHeight(size), height)];
_navItem = [[UINavigationItem alloc] initWithTitle:#"My navbar title"];
[_navBar setItems:#[_navItem]];
[self.view addSubview:_navBar];
Of course you'll have to manage the size a bit differently as my example comes from an app where it's being used in landscape mode.

Center navigation bar title vertically

I have a simple storyboard containing a navigation controller with a static table view controller. I have added a view controller and connected it to one of the cells via a push segue. One thing I have noticed is that the navigation bar title doesn't center properly vertically with the back button and UIBarButtonItem.
Here is an image of what it looks now.
Notice that it is all aligned to the bottom. What I want is, is a way to either move the title down or move the buttons up. If the buttons were moved up, the back button arrow should be moved as well, and allow to return to the main table view.
Here is the code I'm using to set the UIBarButtonItem font in the view controller (If it helps) :
[clearButton setTitleTextAttributes:[NSDictionary dictionaryWithObjectsAndKeys:[UIFont fontWithName:#"ChalkboardSE-Regular" size:15], NSFontAttributeName, [UIColor whiteColor], NSForegroundColorAttributeName, nil] forState:UIControlStateNormal];
And here is what I'm using to set the font for the back button in the app delegate, didFinishLaunchingWithOptions::
[[UIBarButtonItem appearanceWhenContainedIn:[UINavigationBar class], nil] setTitleTextAttributes:#{NSForegroundColorAttributeName:[UIColor whiteColor], NSFontAttributeName:[UIFont fontWithName:#"ChalkboardSE-Regular" size:15]}forState:UIControlStateNormal];
You can move the title down using: [[UINavigationBar appearance] setTitleVerticalPositionAdjustment:(float) forBarMetrics:UIBarMetricsDefault];
SWIFT version for iOS 8+
self.navigationController!.navigationBar.setTitleVerticalPositionAdjustment(adj, forBarMetrics: .Default)
self is a UIViewController:
Note: Consider specifying adjustments for the other bar metrics options, to refine the offset for landscape mode and compact devices, because one offset may not look right on all phones in all positions.
To move title down :
self.navigationController!.navigationBar.setTitleVerticalPositionAdjustmen(+Value, forBarMetrics: .Default)
To move title up:
self.navigationController!.navigationBar.setTitleVerticalPositionAdjustmen(-Value, forBarMetrics: .Default)
In swift 5:
self.navigationBar.setTitleVerticalPositionAdjustment(ajustment, for:.default)

xcode tab controller with customized graphics that won't load until first clicked

I am customizing my TabBar Icons and I'm having a problem with the customized tab graphics not showing up until the first time they are clicked on, except for the first tab. The setup is as follows Entry->VC->Tab Controller->TabVC1->TabVC2->TabVC3->TabVC4->TabVC5. What is the best way to get them showing up on first initialization of the tab controller.
** These attributes are set when I enter the tab controller (they work fine)
// Set background to white for the tab bar
UIImage *tabBackground = [[UIImage imageNamed:#"tabback.png"] resizableImageWithCapInsets:UIEdgeInsetsMake(0, 0, 0, 0)];
[[UITabBar appearance] setBackgroundImage:tabBackground];
// setting the selected color to blue
self.tabBar.tintColor = [UIColor blueColor];
// changing the tab bar text color
[[UITabBarItem appearance] setTitleTextAttributes: [NSDictionary dictionaryWithObjectsAndKeys: [UIColor blackColor], UITextAttributeTextColor,[UIFont fontWithName:#"Copperplate-Bold" size:0.0], UITextAttributeFont, nil] forState:UIControlStateNormal];
** these are set in the individual TabVCs (they show up only after the first time their tab has been clicked)
// loading the custom icon for front and back
UITabBarItem *tabicon = [[UITabBarItem alloc] initWithTitle:#"Daily" image:[UIImage imageNamed:#"Day.png"] tag:0];
[tabicon setFinishedSelectedImage:[UIImage imageNamed:#"Day.png"] withFinishedUnselectedImage:[UIImage imageNamed:#"Day.png"]];
[self setTabBarItem:tabicon];
First of all your tab bar controller should be your root view controller. That is, the rootViewController of your window.
From the documentation:
When deploying a tab bar interface, you must install this view as the
root of your window. Unlike other view controllers, a tab bar
interface should never be installed as a child of another view
controller.
Also, since you call self.tabBar I get the feeling you are subclassing UITabBarController.
The documentation advice against this as well.
That being said, you can set up the tab bar items where ever you do your first appearance set up (the first code snippet).
For instance to alter the second view controllers tab item you would do
// loading the custom icon for front and back
UITabBarItem *tabicon = [[UITabBarItem alloc] initWithTitle:#"Daily" image:[UIImage imageNamed:#"Day.png"] tag:0];
[tabicon setFinishedSelectedImage:[UIImage imageNamed:#"Day.png"] withFinishedUnselectedImage:[UIImage imageNamed:#"Day.png"]];
UIViewController *second = [self.viewControllers objectAtIndex:1];
[second setTabBarItem:tabicon];
The point is that you need to set up the custom appearance before the tab bar view has appeared.
Set the custom tabBarItem in your designated init method. This way it will get set when the controller is initialized and you wont have to wait until it is displayed for the first time to see your custom tabBarItem.
For example, here is an example in Swift, and where the controller is setup in a storyboard:
required init(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
self.tabBarItem = getTabBarItem(NSLocalizedString("Calendar", comment: ""), UIImage(named: "851-calendar.png")!)
}
Note that getTabBarItem() is a custom function of mine that returns a UITabBarItem.

How to get UIBarButtonItem UIViewController?

I have a reference of UIViewController. From that reference i want to get references to all my navigation bar and bar button items and apply custom styles on them.
How can i achieve this on iOS 5?
You can do something like that.
[backbutton setTitleTextAttributes:[NSDictionary dictionaryWithObjectsAndKeys:
[UIColor blackColor],UITextAttributeTextColor,[UIFont fontWithName:TEXTFONT size:16.0f],UITextAttributeFont,
nil] forState:UIControlStateNormal];
Assuming your view controller has a navigation controller, you should be able to access the navigation bar and its items using the following code:
UINavigationBar *navBar = [myViewController.navigationController.navigationBar];
NSArray *navBarItems = navBar.items;

Resources