I want to implement add themes to an app I'm creating. Simply just switching between 2 colors and I want the navigation bars, tool bars etc. to appear in the selected color.
When the app first loads, I apply one color to in the didFinishLaunchingWithOptions method in the AppDelegate.
UIColor *blueTheme = [UIColor colorWithRed:80/255.0f green:192/255.0f blue:224/255.0f alpha:1.0f];
UIColor *pinkTheme = [UIColor colorWithRed:225/255.0f green:87/255.0f blue:150/255.0f alpha:1.0f];
[[UINavigationBar appearance] setBarTintColor:pinkTheme];
[[UIToolbar appearance] setBarTintColor:pinkTheme];
[[UINavigationBar appearance] setTintColor:[UIColor whiteColor]];
And in the first view controller I have put a segmented control to switch the colors.
- (IBAction)themeChosen:(UISegmentedControl *)sender
{
if (sender.selectedSegmentIndex == 0) {
UIColor *blueTheme = [UIColor colorWithRed:80/255.0f green:192/255.0f blue:224/255.0f alpha:1.0f];
[[UINavigationBar appearance] setBarTintColor:blueTheme];
[[UIToolbar appearance] setBarTintColor:blueTheme];
} else {
UIColor *pinkTheme = [UIColor colorWithRed:225/255.0f green:87/255.0f blue:150/255.0f alpha:1.0f];
[[UINavigationBar appearance] setBarTintColor:pinkTheme];
[[UIToolbar appearance] setBarTintColor:pinkTheme];
}
[[UINavigationBar appearance] setTintColor:[UIColor whiteColor]];
}
Say the default theme is pink. I switch to blue from the segmented control and push to the next view controller where there is a UIToolBar as well. The newly chosen color(blue) is applied only to the UIToolBar but not to the UINavigationBar.
Is there a better way to go about this? Also I'd like to put the code related to themes in a separate class because it repeats a lot of code. How do I do that?
Thanks.
The problem you're having is due to the fact that UIAppearance only takes effect the next time a UI control is created. Your new UIToolbar takes on the new appearance because when you push a new viewcontroller it has a brand new toolbar. Your UINavigationBar is not changing, because it was created when your navigationcontroller's view was created, and won't update its appearance.
You'll have to also update the property directly on your navigationController's navigationBar. e.g.:
self.navigationController.navigationBar.barTintColor = blueTheme;
Related
My app uses a blueish color for the navigation bar. I set it globally in the AppDelegate like this:
[[UINavigationBar appearance] setBarTintColor:[UIColor colorWithRed:0.0 green:0.4705882353 blue:0.7450980392 alpha:1.0]];
The problem is that when the user shares a PDF file via email with a UIDocumentInteractionController, the 'Cancel' and 'Send' buttons are also close to blue, which makes them almost invisible.
I tried:
[[UIBarButtonItem appearanceWhenContainedInInstancesOfClasses:#[[UINavigationBar class]]] setTintColor:[UIColor whiteColor]];
and
[[UIButton appearanceWhenContainedInInstancesOfClasses:#[[UINavigationBar class]]] setTintColor:[UIColor whiteColor]];
This works everywhere else in my app, but not on screens presented from the UIDocumentInteractionController.
How can I change the colors of these buttons?
you need to set window tint color if you want to change color of bar button in UIDocumentInteractionController.
Add Below line of code after your code of Set NavigationBar tint color.
[[UINavigationBar appearance] setBarTintColor:[UIColor colorWithRed:0.0 green:0.4705882353 blue:0.7450980392 alpha:1.0]];
// Add this line...
self.window.tintColor = [UIColor whiteColor];
This is working for me.
Note : if you want to reset window tint color use below delegate of UIDocumentInteractionController.
- (void)documentInteractionControllerDidDismissOpenInMenu:controller{
// restore the tintColor which you set # app delegate
self.appDelegate.window.tintColor = [UIColor redColor];
}
Hope this will help you.
I am able to change tho color of NavigationBar by giving BackgroundColor but than I am not able change the color of StatusBar. Please provide a solution.
You should change the barTintColor instead of the background color.
[self.navigationController setBarTintColor:[UIColor redNavigationBarColor]];
Chances are that you will probably need to change also the barButton color and/or the the title color and all that should probably apply to more than one screen. So, to save you some time, if you want to globally change all these, put the code below in your app delegate
[[UINavigationBar appearance] setBarTintColor:[UIColor redColor]];
[[UINavigationBar appearance] setTitleTextAttributes:#{NSForegroundColorAttributeName : [UIColor whiteColor]}];
[[UINavigationBar appearance] setTintColor:[UIColor whiteColor]];
The code above will give you a red navigation bar with white title & buttons
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.
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.
After upgrading Xcode in iOS7.1 my navigation bar and UIToolbar buttons are not shown with correct colour.
When a view first appears the UIToolbar buttons all have the correct default blue colour and when I go to next page/view and come back to the previous view the toolbar buttons are shown in a grey colour.
I have tried to add the blue colour in viewDidLoad and viewWillAppear but no luck. Can someone please help me?
Thanks.
You can set up a theme for certain components all at once and they will be used throughout your application. In my app delegate I created a function when the application is initializing called setupTheme, and it does just that - sets up the "theme" of the application by saying things like [[UINavigationBar appearance] setBarTintColor:], which in effect sets the color of the navigation bar for ANY navigation controller throughout the app. Here's an example from an app that sets up some basic components that are reused so that any time you use them they will already have the correct theme applied.
- (void)setupTheme {
// get our theme colors
UIColor *primaryThemeColor = [UIColor blueColor];
UIColor *secondaryThemeColor = [UIColor whiteColor];
// nav bar
[[UINavigationBar appearance] setBarTintColor:primaryThemeColor];
[[UINavigationBar appearance] setTintColor:secondaryThemeColor];
[[UINavigationBar appearance] setTitleTextAttributes:#{NSForegroundColorAttributeName:secondaryThemeColor}];
// tab bar
[[UITabBar appearance] setTintColor:primaryThemeColor];
// switches
[[UISwitch appearance] setOnTintColor:primaryThemeColor];
// search bar
[[UIBarButtonItem appearanceWhenContainedIn:[UISearchBar class], nil] setTitleTextAttributes:#{NSForegroundColorAttributeName: [UIColor blackColor]} forState:UIControlStateNormal];
}
Check out the iOS 7 transition guide for more details on specifics https://developer.apple.com/library/iOs/documentation/UserExperience/Conceptual/TransitionGuide/Bars.html#//apple_ref/doc/uid/TP40013174-CH8-SW1