I keep reading to change the default color on a navigationbar i just need to update the first method in the appdelegate to this
self.window.rootViewController.navigationController.navigationBar.tintColor = [UIColor whiteColor];
but it doesn't seem to work, so I tried setting it in the viewDidLoad method of the firstview also:
self.parentViewController.navigationController.navigationBar.tintColor = [UIColor whiteColor];
This didn't work either. How can I change this?
Don't use self.parentViewController, but self:
self.navigationController.navigationBar.tintColor = [UIColor whiteColor];
When iphone 5 come we have to set both device type. So use this
if([self.navigationController.navigationBar respondsToSelector:#selector(setBackgroundImage:forBarMetrics:)] ) {
//iOS 5 new UINavigationBar custom background
[self.navigationController.navigationBar setBackgroundImage:[UIImage imageNamed:#"navbg_ForiPhone5_Imagename.png"] forBarMetrics: UIBarMetricsDefault];
} else {
[self.navigationController.navigationBar insertSubview:[[UIImageView alloc] initWithImage:[UIImage imageNamed:#"navbg_ForOtherIphone_Imagename.png"]] atIndex:0];
}
In IOS7 you can try this:
[[UINavigationBar appearance] setBarTintColor:[UIColor redColor]];
You can follow these steps:
I created a new UINavigationController for example UIDemoNavController resulting in:
- (void)viewDidLoad{
[[UINavigationBar appearance] setBarTintColor:[UIColor redColor]];
[super viewDidLoad];
}
This is the full demo class:
#import "UIDemoNavController.h"
#interface UIDemoNavController()
#end
#implementation UIDemoNavController
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil{
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {}
return self;
}
- (void)viewDidLoad{
[[UINavigationBar appearance] setBarTintColor:[UIColor redColor]];
[super viewDidLoad];
}
- (void)didReceiveMemoryWarning{
[super didReceiveMemoryWarning];
}
#end
Try self.navigationController.navigationBar.tintColor = [UIColor whiteColor];
UIViewController class has a property navigationController, which returns the navigation controller its embedded in no matter how deep, otherwise it returns nil.
Related
I am facing a weird bug, that happens only on iOS 10.
I have a application with several screens, and each screen colors the navigationBar in viewWillAppear. So when you go to the next screen, it will be properly colored.
However, when testing on iOS 10 I suddenly see the following behaviour when going back to a previous screen:
When the previous screen appears the navigationBar still has the color of the previous screen and then flashes to the proper color.
It almost looks like viewWillAppear somehow behaves as viewDidAppear.
Relevant code:
ViewController:
- (void)viewWillAppear:(BOOL)animated
{
[super viewWillAppear:animated];
[ViewControllerPainter paint:self withBackground:[UIColor whiteColor] andForeground:[UIColor blackColor] andIsLight:true];
}
Painter:
+ (void)paint:(UIViewController *)controller withBackground:(UIColor *)backgroundColor andForeground:(UIColor *)foregroundColor andIsLight:(bool)isLight
{
controller.navigationController.navigationBar.opaque = true;
controller.navigationController.navigationBar.translucent = false;
controller.navigationController.navigationBar.tintColor = foregroundColor;
controller.navigationController.navigationBar.barTintColor = backgroundColor;
controller.navigationController.navigationBar.backgroundColor = backgroundColor;
controller.navigationController.navigationBar.barStyle = isLight ? UIBarStyleDefault : UIBarStyleBlack;
controller.navigationController.navigationBar.titleTextAttributes = #{NSForegroundColorAttributeName: foregroundColor};
}
Is this a bug? Is there something I can do about to fix this? It's very frustrating.
Here's what changed according to the iOS 10 SDK Release Notes:
In iOS 10, UIKit has updated and unified background management for UINavigationBar, UITabBar, and UIToolbar. In particular, changes to background properties of these views (such as background or shadow images, or setting the bar style) may kick off a layout pass for the bar to resolve the new background appearance.
In particular, this means that attempts to change the background appearance of these bars inside of -[UIView layoutSubviews], -[UIView updateConstraints], -[UIViewController willLayoutSubviews], -[UIViewController didLayoutSubviews], - [UIViewController updateViewConstraints], or any other method that is called in response to layout may result in a layout loop.
So the problem seems to be that viewWillAppear is triggering the mentioned layout loop, since it's called as a result of a layout change:
The quick fix for me was overriding popViewControllerAnimated and pushViewController and updating the navigationBar background on my subclass of UINavigationController. Here's how it looks like:
override func popViewControllerAnimated(animated: Bool) -> UIViewController? {
let poppedViewController = super.popViewControllerAnimated(animated)
// Updates the navigation bar appearance
updateAppearanceForViewController(nextViewController)
return poppedViewController
}
override func pushViewController(viewController: UIViewController, animated: Bool) {
super.pushViewController(viewController, animated: animated)
// Updates the navigation bar appearance
updateAppearanceForViewController(viewController)
}
My guess is that it works because popViewControllerAnimated and pushViewController are not called by the OS as a result of a layout change, but by a touch event. So keep that in mind if you want to find another place to update your navigationBar background.
I had to fix this with:
self.navigationController.navigationBarHidden = YES;
self.navigationController.navigationBarHidden = NO;
This way you don't have to override popviewcontroller or pushviewcontroller. It's basically triggering the navigationbar to redraw.
It's still annoying how they can just push out a new version of OS that breaks something this significant.
Try using willMoveToParentViewController, gives the same effect as overriding UINavigationController methods but without the hassle.
I am posting the solution for Objective-C (subclass of UINavigationController):
#import "FUINavigationController.h"
#interface FUINavigationController ()
#end
#implementation FUINavigationController
- (void)viewDidLoad {
[super viewDidLoad];
NSLog(#"current: %#",[self.topViewController class]);
if ([NSStringFromClass([self.topViewController class]) isEqualToString:#"LoginVC"]) {
[self setNavBarHidden];
}
// Do any additional setup after loading the view.
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
-(UIViewController*)popViewControllerAnimated:(BOOL)animated {
UIViewController *popedVC = [super popViewControllerAnimated:animated];
if ([NSStringFromClass([popedVC class]) isEqualToString:#"SignUpVC"] && [NSStringFromClass([[super topViewController] class]) isEqualToString:#"LoginVC"]) {
[self setNavBarHidden];
}
return popedVC;
}
-(void)pushViewController:(UIViewController *)viewController animated:(BOOL)animated {
[super pushViewController:viewController animated:animated];
[self setNavBarVisible];
}
-(void)setNavBarHidden {
[self.navigationBar setBackgroundImage:[UIImage new] forBarMetrics:UIBarMetricsDefault];
[self.navigationBar setShadowImage:[UIImage new]];
[self.navigationBar setTranslucent:YES];
[self.navigationBar setBackgroundColor:[UIColor clearColor]];
}
-(void)setNavBarVisible {
[self.navigationBar setBackgroundColor:[UIColor grayColor]];
[self.navigationBar setBarTintColor:[UIColor grayColor]];
[self.navigationBar setTintColor:[UIColor whiteColor]];
[self.navigationBar setTranslucent:NO];
[self.navigationBar setTitleTextAttributes:#{NSForegroundColorAttributeName :[UIColor whiteColor]}];
[self.navigationBar setTitleTextAttributes:[NSDictionary dictionaryWithObjectsAndKeys: [UIColor whiteColor], NSForegroundColorAttributeName, [UIFont fontWithName:#"Roboto-Reqular" size:18], NSFontAttributeName,nil]];
[self.navigationBar.topItem setBackBarButtonItem:[[UIBarButtonItem alloc] initWithTitle:#"" style:UIBarButtonItemStylePlain target:nil action:nil]];
}
#end
OR using method swizzling:
#import <objc/runtime.h>
#import "UINavigationController+FadeOutNavigationBar.h"
#implementation UINavigationController (FadeOutNavigationBar)
+(void)load {
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
Class class = [self class];
//Swizzling view will appear
SEL originalSelectorVWA = #selector(viewWillAppear:);
SEL swizzledSelectorVWA = #selector(swizzled_viewWillAppear:);
Method originalMethodVWA = class_getInstanceMethod(class, originalSelectorVWA);
Method swizzledMethodVWA = class_getInstanceMethod(class, swizzledSelectorVWA);
BOOL didAddMethodVWA =
class_addMethod(class,
originalSelectorVWA,
method_getImplementation(swizzledMethodVWA),
method_getTypeEncoding(swizzledMethodVWA));
if (didAddMethodVWA) {
class_replaceMethod(class,
swizzledSelectorVWA,
method_getImplementation(originalMethodVWA),
method_getTypeEncoding(originalMethodVWA));
} else {
method_exchangeImplementations(originalMethodVWA, swizzledMethodVWA);
}
//Swizzling popViewControllerAnimated
SEL originalSelectorPVCA = #selector(popViewControllerAnimated:);
SEL swizzledSelectorPVCA = #selector(swizzled_popViewControllerAnimated:);
Method originalMethodPVCA = class_getInstanceMethod(class, originalSelectorPVCA);
Method swizzledMethodPVCA = class_getInstanceMethod(class, swizzledSelectorPVCA);
BOOL didAddMethodPVCA =
class_addMethod(class,
originalSelectorPVCA,
method_getImplementation(swizzledMethodPVCA),
method_getTypeEncoding(swizzledMethodPVCA));
if (didAddMethodPVCA) {
class_replaceMethod(class,
swizzledSelectorVWA,
method_getImplementation(originalMethodPVCA),
method_getTypeEncoding(originalMethodPVCA));
} else {
method_exchangeImplementations(originalMethodPVCA, swizzledMethodPVCA);
}
//Swizzling pushViewController
SEL originalSelectorPVC = #selector(pushViewController:animated:);
SEL swizzledSelectorPVC = #selector(swizzled_pushViewController:animated:);
Method originalMethodPVC = class_getInstanceMethod(class, originalSelectorPVC);
Method swizzledMethodPVC = class_getInstanceMethod(class, swizzledSelectorPVC);
BOOL didAddMethodPVC =
class_addMethod(class,
originalSelectorPVC,
method_getImplementation(swizzledMethodPVC),
method_getTypeEncoding(swizzledMethodPVC));
if (didAddMethodPVC) {
class_replaceMethod(class,
swizzledSelectorPVC,
method_getImplementation(originalMethodPVC),
method_getTypeEncoding(originalMethodPVC));
} else {
method_exchangeImplementations(originalMethodPVC, swizzledMethodPVC);
}
});
}
#pragma mark - Method Swizzling
- (void)swizzled_viewWillAppear:(BOOL)animated {
[self swizzled_viewWillAppear:animated];
NSLog(#"current: %#",[self.topViewController class]);
if ([NSStringFromClass([self.topViewController class]) isEqualToString:#"LoginVC"]) {
[self setNavBarHidden];
}
}
-(void)setNavBarHidden {
[self.navigationBar setBackgroundImage:[UIImage new] forBarMetrics:UIBarMetricsDefault];
[self.navigationBar setShadowImage:[UIImage new]];
[self.navigationBar setTranslucent:YES];
[self.navigationBar setBackgroundColor:[UIColor clearColor]];
}
-(void)setNavBarVisible {
[self.navigationBar setBackgroundColor:[UIColor grayColor]];
[self.navigationBar setBarTintColor:[UIColor grayColor]];
[self.navigationBar setTintColor:[UIColor whiteColor]];
[self.navigationBar setTranslucent:NO];
[self.navigationBar setTitleTextAttributes:#{NSForegroundColorAttributeName :[UIColor whiteColor]}];
[self.navigationBar setTitleTextAttributes:[NSDictionary dictionaryWithObjectsAndKeys: [UIColor whiteColor], NSForegroundColorAttributeName, [UIFont fontWithName:#"Roboto-Reqular" size:18], NSFontAttributeName,nil]];
[self.navigationBar.topItem setBackBarButtonItem:[[UIBarButtonItem alloc] initWithTitle:#"" style:UIBarButtonItemStylePlain target:nil action:nil]];
}
-(UIViewController*)swizzled_popViewControllerAnimated:(BOOL)animated {
UIViewController *popedVC = [self swizzled_popViewControllerAnimated:animated];
if ([NSStringFromClass([popedVC class]) isEqualToString:#"SignUpVC"] && [NSStringFromClass([[self topViewController] class]) isEqualToString:#"LoginVC"]) {
[self setNavBarHidden];
}
return popedVC;
}
-(void)swizzled_pushViewController:(UIViewController *)viewController animated:(BOOL)animated {
[self swizzled_pushViewController:viewController animated:animated];
[self setNavBarVisible];
}
#end
In my iOS App I have the below code snipped repeating over and over again in every class.
I have tried to cast the method into a NSObject class but I receive errors for the use of "navigationItem".
-(void)customDesign {
//background pattern
self.view.backgroundColor = [[UIColor alloc] initWithPatternImage:[UIImage imageNamed:#"BG-pattern.png"]];
// nav bar
[self.navigationController.navigationBar setBackgroundImage:[UIImage imageNamed:#"top_bar.png"] forBarMetrics:UIBarMetricsDefault];
//back button color #2974c3
[self.navigationController.navigationBar setTintColor:[UIColor colorWithRed:41.0/255.0f green:116.0/255.0f blue:195.0/255.0f alpha:1.0]];
//settings button
UIImage* settingsImage = [UIImage imageNamed:#"ButtonMenu.png"];
CGRect frameimg = CGRectMake(0, 0, settingsImage.size.width, settingsImage.size.height);
UIButton *uiSettingsButton = [[UIButton alloc] initWithFrame:frameimg];
[uiSettingsButton setBackgroundImage:settingsImage forState:UIControlStateNormal];
[uiSettingsButton addTarget:self action:#selector(menuButton) forControlEvents:UIControlEventTouchUpInside];
[uiSettingsButton setShowsTouchWhenHighlighted:YES];
//add buton to navbar
UIBarButtonItem *settingsButton = [[UIBarButtonItem alloc] initWithCustomView:uiSettingsButton];
self.navigationItem.leftBarButtonItem = settingsButton;
}
You should be creating your own subclass of UIViewController or UITableViewController (whichever you're using) and place this code in your viewDidLoad method of that subclass. All the controllers that need this code can then extend your custom class. This will save you the hassle of having to write this code everywhere.
Your custom subclass:
#interface CustomViewController : UIViewController
#end
Your viewDidLoad method in the subclass:
#implementation CustomViewController
- (void)viewDidLoad {
[super viewDidLoad];
// all your custom code here...
}
#end
Extend your custom class for controllers you want to have common stuff done in:
#interface VisuallyChangedViewController : CustomViewController
#end
#implementation VisuallyChangedViewController
- (void)viewDidLoad {
[super viewDidLoad];
}
#end
QLPreviewController * preview = [[QLPreviewController alloc] init];
preview.dataSource = self;
preview.currentPreviewItemIndex = sender.tag;
preview.editing= YES;
[self presentModalViewController:preview animated:YES];
[preview release];
These two lines does not work for me. so be careful before writing these lines.
[preview.tabBarController.tabBar setTintColor:[UIColor blackColor]];
[preview navigationController].navigationBar setTintColor: [UIColor blackColor]];
Since iOS5 you can theme controls based on instance, globally or when contained by specific container classes. Since iOS6 the former method of subclassing QLPreviewController to set the tintColor of the UINavigationBar stopped working.
Consider one of the following as an example of a workaround that is compatible with iOS5 and iOS6:
Any UINavigationBar contained within a QLPreviewController:
[[UINavigationBar appearanceWhenContainedIn:[QLPreviewController class], nil]
setTintColor:[UIColor blackColor]];
or globally set the tintColor of all UINavigationBar instances within your app with:
[[UINavigationBar appearance] setTintColor:[UIColor blackColor]];
This same strategy works with the UITabBarController.
set style of UINavigationController with this line..
self.navigationController.navigationBar.barStyle = UIBarStyleBlack;
and for change the color of TabBar just Add the below code in viewWillAppear of your class
CGRect frame = CGRectMake(0.0, 0.0, self.view.bounds.size.width, 48);
UIView *v = [[UIView alloc] initWithFrame:frame];
[v setBackgroundColor:[UIColor colorWithRed:0.1 green:0.2 blue:0.6 alpha:0.8]];
[v setAlpha:0.5];
[[self.tabBarController tabBar] insertSubview:v atIndex:0];
[v release];
If you want to change the tintColor of the navigationBar you can push your QLPreviewController instead present it modally:
//i assume that you already have a navigationController
[[self navigationController] pushViewController:previewer animated:YES];
[self.navigationController.navigationBar setTintColor:[UIColor blackColor]];
For the bottom bar i think that is a UIToolbar not a UITabBar, probably you cant change the color (i dont know), but surely you can't call preview.tabBarController.tabBar.
I found a solution , though it is not the correct way but it works:
Make subclass of QLPreviewController
MyQLPreviewController.h
#interface MyQLPreviewController : QLPreviewController
#end
and in .m of that new subclass, copy the following code
#implementation MyQLPreviewController
- (void)viewWillAppear:(BOOL)animated
{
[super viewWillAppear:animated];
UIToolbar *toolbar = [self getToolBarFromView:self.view]; //NOTE: Not the correct apperoach! could not think better solution, as iOS does not allow to access the toolbar properties in QLPreviewController
toolbar.barTintColor = [UIColor redColor];
}
- (UIToolbar *)getToolBarFromView:(UIView *)view
{
for (UIView *subView in view.subviews)
{
if ([subView isKindOfClass:[UIToolbar class]])
{
return (UIToolbar *)subView;
}
else
{
UIToolbar *toolBar = [self getToolBarFromView:subView];
if (toolBar)
{
return toolBar;
}
}
}
return nil;
}
How do I go about changing the tab bar color in this code? My tab bar is black. On click changes it to blue. I want to change the tow color to any other color.
This code is from :application.m
and there :rotatingTabBarController.m ,rotatingTabBarController.h
// 1B) If this app uses tabs, create a tabbed navigation application and set the default screen for each tab
// to the defaultScreenGuid in the tabs data
if([self.tabs count] > 0){
[BT_debugger showIt:self:[NSString stringWithFormat:#"building a tabbed based navigation app%#", #""]];
if([self.screens count] > 0){
//appDelegate
qoqb_appDelegate *appDelegate = (qoqb_appDelegate *)[[UIApplication sharedApplication] delegate];
//initialize the tab bar controller
rootTabBarController = [[BT_rotatingTabBarController alloc] init];
[rootTabBarController.view setFrame:[[UIScreen mainScreen] bounds]];
[rootTabBarController setDelegate:appDelegate];
rootTabBarController.view.autoresizingMask = (UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight);
//if we have a tabbar color setup in the theme
if(self.rootTheme != nil){
if([self.rootTheme.jsonVars objectForKey:#"tabBarColor"]){
if([[self.rootTheme.jsonVars objectForKey:#"tabBarColor"] length] > 3){
UIColor *tabberColor = [BT_color getColorFromHexString:[self.rootTheme.jsonVars objectForKey:#"tabBarColor"]];
NSString *tabberOpacity = #".50";
if([self.rootTheme.jsonVars objectForKey:#"tabBarColorOpacity"]){
if([[self.rootTheme.jsonVars objectForKey:#"tabBarColorOpacity"] length] > 0){
tabberOpacity = [NSString stringWithFormat:#".%#", [self.rootTheme.jsonVars objectForKey:#"tabBarColorOpacity"]];
if([tabberOpacity isEqualToString:#".100"]) tabberOpacity = #".50";
}
//colorize the tab-bar
[rootTabBarController addTabColor:tabberColor:[tabberOpacity doubleValue]];
}
}
}
}
//Fill a temporary array of view controllers to assign to tab bar controller
NSMutableArray *tmpViewControllers = [[NSMutableArray alloc] init];
//loop through each tab bar item in application data
for(int i = 0; i < [[self tabs] count]; i++){
//this tab
BT_item *thisTab = (BT_item *)[[self tabs] objectAtIndex:i];
NSString *textLabel = [[thisTab jsonVars] objectForKey:#"textLabel"];
UIImage *tabIcon = [UIImage imageNamed:[[thisTab jsonVars] objectForKey:#"iconName"]];
//get the screen from the apps array of screens for this tab's view controller
if([[thisTab jsonVars] objectForKey:#"homeScreenItemId"]){
BT_item *thisTabsDefaultScreenData = [self getScreenDataByItemId:[[thisTab jsonVars] objectForKey:#"homeScreenItemId"]];
//if this is the first tab in the list, remember it as the "currently loaded screen", also make it the "previously loaded screen"
if(i == 0){
[self setCurrentScreenData:thisTabsDefaultScreenData];
[self setPreviousScreenData:thisTabsDefaultScreenData];
[thisTabsDefaultScreenData setIsHomeScreen:TRUE];
//if theScreen has an audio file..load it in the delegate
if([[BT_strings getJsonPropertyValue:thisTabsDefaultScreenData.jsonVars:#"audioFileName":#""] length] > 3){
//appDelegate
qoqb_appDelegate *appDelegate = (qoqb_appDelegate *)[[UIApplication sharedApplication] delegate];
//initialize audio in different thread to prevent UI blocking
[NSThread detachNewThreadSelector: #selector(loadAudioForScreen:) toTarget:appDelegate withObject:thisTabsDefaultScreenData];
}
}
tabBar.tintColor = [UIColor greenColor];
will crash if your IOS version is not IOS 5 see the docs
a safer approach is:
if ([tabBarController.tabBar respondsToSelector:#selector(setTintColor:)]) {
[tabBarController.tabBar setTintColor:color];
}
//NEW CODE
if ([rootTabBarController.tabBar respondsToSelector:#selector(setTintColor:)]) {
[rootTabBarController.tabBar setTintColor:tabberColor];
}
In the AppDelegate.m inside at: application didFinishLaunchingWithOptions:
Using this coding:
// use this for highlighted color
[[UITabBar appearance] setSelectedImageTintColor:[UIColor colorWithRed:(256/256.0) green:(0/256.0) blue:(0/256.0) alpha:(1.0)]];
// Use this to channge the tint colo of the entere TabBar
[[UITabBar appearance] setTintColor:[UIColor colorWithRed:(255/256.0) green:(0/256.0) blue:(0/256.0) alpha:(1.0)]];
// This change only a background color
[[UITabBar appearance] setBackgroundColor:[UIColor colorWithRed:(255/256.0) green:(255/256.0) blue:(255/256.0) alpha:1.0]];
// This for change IMG or color tint on back of highlighted button.
[[UITabBar appearance] setSelectionIndicatorImage:[UIImage imageNamed:#"YourIMG.png"]];
That's it that's all ;)
tabBar.tintColor = [UIColor greenColor];
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
self.tabBarController.tabBar.tintColor=[UIColor redColor];
return YES;
}
In AppDelegate.m
In IOS7 this is done differently:
[[UINavigationBar appearance] setBarTintColor:[UIColor redColor]];
You can follow these steps:
I created a new UINavigationController for example UIDemoNavController resulting in:
- (void)viewDidLoad{
[[UINavigationBar appearance] setBarTintColor:[UIColor redColor]];
[super viewDidLoad];
}
This is the full demo class:
#import "UIDemoNavController.h"
#interface UIDemoNavController()
#end
#implementation UIDemoNavController
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil{
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {}
return self;
}
- (void)viewDidLoad{
[[UINavigationBar appearance] setBarTintColor:[UIColor redColor]];
[super viewDidLoad];
}
- (void)didReceiveMemoryWarning{
[super didReceiveMemoryWarning];
}
#end
Is it possible to give a UIToolBar a custom background from an image rather than the usual tinted blue/black fade out?
I've tried giving the view a background and setting the opacity of the UIToolBar but that also affects the opacity of any UIBarButtons on it.
Answering my own question here!!! Overriding the drawRect function and creating an implementation of the UIToolbar does the trick :)
#implementation UIToolbar (CustomImage)
- (void)drawRect:(CGRect)rect {
UIImage *image = [UIImage imageNamed: #"nm010400.png"];
[image drawInRect:CGRectMake(0, 0, self.frame.size.width, self.frame.size.height)];
}
#end
UIToolbar inherits from UIView. This just worked for me:
[topBar insertSubview:[[[UIImageView alloc] initWithImage:[UIImage imageNamed:BAR_BKG_IMG]] autorelease] atIndex:0];
Slightly modified version of loreto's answer, which works for me on ios 4 and 5:
// Set the background of a toolbar
+(void)setToolbarBack:(NSString*)bgFilename toolbar:(UIToolbar*)toolbar {
// Add Custom Toolbar
UIImageView *iv = [[UIImageView alloc] initWithImage:[UIImage imageNamed:bgFilename]];
iv.frame = CGRectMake(0, 0, toolbar.frame.size.width, toolbar.frame.size.height);
iv.autoresizingMask = UIViewAutoresizingFlexibleWidth;
// Add the tab bar controller's view to the window and display.
if([[[UIDevice currentDevice] systemVersion] intValue] >= 5)
[toolbar insertSubview:iv atIndex:1]; // iOS5 atIndex:1
else
[toolbar insertSubview:iv atIndex:0]; // iOS4 atIndex:0
toolbar.backgroundColor = [UIColor clearColor];
}
This is the approach I use for iOS 4 and 5 compatibility:
if ([toolbar respondsToSelector:#selector(setBackgroundImage:forToolbarPosition:barMetrics:)]) {
[toolbar setBackgroundImage:[UIImage imageNamed:#"toolbar-background"] forToolbarPosition:UIToolbarPositionAny barMetrics:UIBarMetricsDefault];
} else {
[toolbar insertSubview:[[[UIImageView alloc] initWithImage:[UIImage imageNamed:#"toolbar-background"]] autorelease] atIndex:0];
}
just add this piece to your -(void)viewDidLoad{}
[toolBarName setBackgroundImage:[UIImage imageNamed:#"imageName.png"] forToolbarPosition:UIToolbarPositionAny barMetrics:UIBarMetricsDefault];
If you use idimmu's answer and want your barbuttonitems to be colored instead of the defaults, you can add these couple of lines of code as well to your category:
UIColor *color = [UIColor redColor];
self.tintColor = color;
You can use the Appearance API since iOS5:
[[UIToolbar appearance] setBackgroundImage:[UIImage imageNamed:#"navbar_bg"] forToolbarPosition:UIToolbarPositionAny barMetrics:UIBarMetricsDefault];
To be iOS 5 compliant you can do something like this
-(void) addCustomToolbar {
// Add Custom Toolbar
UIImageView *img = [[UIImageView alloc] initWithImage:[UIImage imageNamed:#"customToolbar.png"]];
img.frame = CGRectMake(-2, -20, img.frame.size.width+4, img.frame.size.height);
// Add the tab bar controller's view to the window and display.
if( SYSTEM_VERSION_GREATER_THAN_OR_EQUAL_TO( #"5.0" ) )
[self.tabBarController.tabBar insertSubview:img atIndex:1]; // iOS5 atIndex:1
else
[self.tabBarController.tabBar insertSubview:img atIndex:0]; // iOS4 atIndex:0
self.tabBarController.tabBar.backgroundColor = [UIColor clearColor];
// Override point for customization after application launch.
[self.window addSubview:tabBarController.view];
}
this one works fine for me:
ToolbarOptions *tbar = [[ToolbarOptions alloc] init];
[tbar setToolbarBack:#"footer_bg.png" toolbar:self.toolbarForPicker];
[tbar release];
#import <Foundation/Foundation.h>
#interface ToolbarOptions : NSObject {
}
-(void)setToolbarBack:(NSString*)bgFilename toolbar:(UIToolbar*)toolbar;
#end
#import "ToolbarOptions.h"
#implementation ToolbarOptions
-(void)setToolbarBack:(NSString*)bgFilename toolbar:(UIToolbar*)bottombar {
// Add Custom Toolbar
UIImageView *iv = [[UIImageView alloc] initWithImage:[UIImage imageNamed:bgFilename]];
iv.frame = CGRectMake(0, 0, bottombar.frame.size.width, bottombar.frame.size.height);
iv.autoresizingMask = UIViewAutoresizingFlexibleWidth;
// Add the tab bar controller's view to the window and display.
if([[[UIDevice currentDevice] systemVersion] intValue] >= 5)
[bottombar insertSubview:iv atIndex:1]; // iOS5 atIndex:1
else
[bottombar insertSubview:iv atIndex:0]; // iOS4 atIndex:0
bottombar.backgroundColor = [UIColor clearColor];
}
#end
You can do this with a category that basically adds a new property to UIToolBar. Overriding drawRect can work but it's not necessarily future proof. That same strategy for custom UINavigationBar stopped working with iOS 6.
Here's how I'm doing it.
.h file
#interface UIToolbar (CustomToolbar)
#property (nonatomic, strong) UIView *customBackgroundView;
#end
.m file
#import "CustomToolbar.h"
#import
static char TIToolbarCustomBackgroundImage;
#implementation UIToolbar (CustomToolbar)
- (void)setCustomBackgroundView:(UIView *)newView {
UIView *oldBackgroundView = [self customBackgroundView];
[oldBackgroundView removeFromSuperview];
[self willChangeValueForKey:#"tfCustomBackgroundView"];
objc_setAssociatedObject(self, &TIToolbarCustomBackgroundImage,
newView,
OBJC_ASSOCIATION_RETAIN);
[self didChangeValueForKey:#"tfCustomBackgroundView"];
if (newView != nil) {
[self addSubview:newView];
}
}
- (UIView *)customBackgroundView {
UIView *customBackgroundView = objc_getAssociatedObject(self, &TIToolbarCustomBackgroundImage);
return customBackgroundView;
}
#end
In your view controller code, e.g. viewDidLoad
if (self.navigationController.toolbar.customBackgroundView == nil) {
self.navigationController.toolbar.customBackgroundView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:#"navigation_bar_background.png"]];
self.navigationController.toolbar.customBackgroundView.autoresizingMask = UIViewAutoresizingFlexibleHeight | UIViewAutoresizingFlexibleWidth;
}