Can I give a UIToolBar a custom background in my iPhone app?
Asked Answered
R

10

24

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.

Roane answered 21/12, 2009 at 16:28 Comment(0)
R
40

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
Roane answered 21/12, 2009 at 17:42 Comment(7)
You are creating a "category" on UIToolbar.Danged
This works thanks, but I think it's better to subclass the UIToolbar.Brief
Should you need a call to [super drawRect:] in there? How does it know the draw the buttons or other elements?Decree
I believe all of the other elements are subviews and so don't need to be drawn by drawRect.Questor
What about simply drawInRect:self.bounds?Bailable
Very sneaky - it worked for me. I may wait for my upgrade to iOS 5 which supports customization with callbacks.Irritant
But didn't find it working with 4.3 :(. It works well in previous iOS 4.2 but not with 4.3.Amuck
B
16

UIToolbar inherits from UIView. This just worked for me:

[topBar insertSubview:[[[UIImageView alloc] initWithImage:[UIImage imageNamed:BAR_BKG_IMG]] autorelease] atIndex:0];
Bourg answered 8/8, 2010 at 23:23 Comment(0)
C
10

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];
}
Coroner answered 22/7, 2011 at 2:10 Comment(3)
In iOS 5 there are new APIs that allow the customization of the controls. There is no need to insert a subview. Also, checking for the system version is not the recommended practice, respondsToSelector is a much more robust alternative.Headsail
I don't see anything wrong with checking the system version. How is respondsToSelector more robust?Strychnine
@diablosnuevos - if you check for system version now, you will always have to keep modifying your code when new versions release. respondsToSelector is independent from system version. That said, this method will respond to insertSubview regardless of version, so that respondsToSelector is not appropriate here.Macle
D
9

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];
}
Dhar answered 23/2, 2012 at 7:10 Comment(3)
Hi Christopher, I am implementing this solution but I still get to see the highlight on the toolbar (that Apple standard highlight over the top half of the toolbar). Do you know if there is a way to switch off that highlight?Oxy
@MadOxyn strange, I don't see that highlight. What iOS version do you see this on?Dhar
I was seeing it on both iOS4 & 5, but I got the issue now. I was stupid, there is a paging control laying over it with a semi-transparent white background which is causing that highlight. I didn't realize this. Your reply made me think again ;) Thanks.Oxy
K
7

just add this piece to your -(void)viewDidLoad{}

[toolBarName setBackgroundImage:[UIImage imageNamed:@"imageName.png"] forToolbarPosition:UIToolbarPositionAny barMetrics:UIBarMetricsDefault];
Kingdon answered 3/7, 2012 at 1:2 Comment(0)
R
2

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;
Ramon answered 19/8, 2010 at 4:5 Comment(0)
F
2

You can use the Appearance API since iOS5:

[[UIToolbar appearance] setBackgroundImage:[UIImage imageNamed:@"navbar_bg"] forToolbarPosition:UIToolbarPositionAny barMetrics:UIBarMetricsDefault];
Fellatio answered 5/6, 2013 at 10:43 Comment(0)
T
1

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];

}
Tasteless answered 1/7, 2011 at 9:56 Comment(2)
Works great! The category method didn't work for me for some reasonCoroner
Just had to change the if statement to: if([[[UIDevice currentDevice] systemVersion] intValue] >= 5)Coroner
B
0

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
Blithesome answered 29/8, 2011 at 16:44 Comment(0)
N
0

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;
    }
Niblick answered 28/10, 2012 at 19:40 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.