I'm using the following categories code to change
the background image of the navigation bar
#import <Foundation/Foundation.h>
#interface UINavigationBar (CustomImage)
- (void) setBackgroundImage:(UIImage*)image;
- (void) clearBackgroundImage;
#end
#import "UINavigationBar+CustomImage.h"
#implementation UINavigationBar (CustomImage)
- (void) setBackgroundImage:(UIImage*)image {
if (image == NULL) return;
UIImageView *imageView = [[UIImageView alloc] initWithImage:image];
imageView.frame = CGRectMake(0, 0, self.frame.size.width, self.frame.size.height);
[self insertSubview:imageView atIndex:0];
[imageView release];
}
- (void) clearBackgroundImage {
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
NSArray *mySubviews = [self subviews];
for (int i = [mySubviews count] - 1; i >= 0; i--)
{
if ([[mySubviews objectAtIndex:i] isMemberOfClass:[UIImageView class]])
{
[[mySubviews objectAtIndex:i] removeFromSuperview];
return;
}
}
[pool release];
}
#end
And i'm using the following code to generate the custom back button
in my view
UIButton *btnBack = [[UIButton alloc] initWithFrame:CGRectMake(0, 0, 40, 40)];
[btnBack addTarget:self action:#selector(goBack) forControlEvents:UIControlEventTouchUpInside];
[btnBack setImage:[UIImage imageNamed:#"back.png"] forState:UIControlStateNormal];
UIBarButtonItem *barBtnBack = [[UIBarButtonItem alloc] initWithCustomView:btnBack];
self.navigationItem.leftBarButtonItem = barBtnBack;
[btnBack release];
[barBtnBack release];
But the button most of the time is hidden under the bg image
and some times it randomly appears.
Why is this happening? I'm not sure what's the problem the image is inserted at index 0
so as I understand it is supposed to be behind all the time.
Please help.
Try the following code to change background of the navigation bar in the class where you are loading the navigation bar.
#interface UINavigationBar (MyCustomNavBar)
#end
#implementation UINavigationBar (MyCustomNavBar)
- (void) drawRect:(CGRect)rect
{
UIImage *barImage = [UIImage imageNamed:#"image.png" ];
[barImage drawInRect:rect];
}
#end
Using the method Praveen S suggested you could have a global variable for the next background image name and set it in your viewDidLoad method, then in your draw rect method use the imageName stored in the variable rather than hardcoding it in the draw rect.
You should try creating the button after adding the image.
Related
I am trying to change the background color and make an image appear on the screen when a button is pushed. I can get the color to change, but I can't get a trace of the image to appear. I don't know how to place the image on the screen either. I am using iOS 5 and storyboard, but I have not added the UIImageView to the storyboard, as I want it to appear.
My ViewController.h
#import <UIKit/UIKit.h>
#interface ViewController : UIViewController
- (IBAction)changeButton:(id)sender;
#end
My ViewController.m
#import "ViewController.h"
#interface ViewController ()
#end
#implementation ViewController
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
-(void)colorchange
{
self.view.backgroundColor = [UIColor greenColor];
}
-(void)imageShow
{
UIImage *image = [UIImage imageNamed:#"logo-tag-centered.pmg"];
UIImageView *imgView = [[UIImageView alloc] initWithFrame:CGRectMake(0, 0, 0, 0)];
[imgView setImage:image];
}
- (IBAction)changeButton:(id)sender
{
[self colorchange];
[self imageShow];
}
#end
Any help would be greatly appreciated! Thanks!
You have to add the image view to your view controller's view.
- (void)showImage
{
UIImage *image = [UIImage imageNamed:#"logo-tag-centered.png"];
UIImageView *imgView = [[UIImageView alloc] initWithImage:image];
imgView.center = CGPointMake(self.view.bounds.size.width / 2.0f, self.view.bounds.size.height / 2.0f);
[self.view addSubview:imgView];
}
You haven't added the image view anywhere to the main view. You could do this:
- (void)viewDidLoad
{
[super viewDidLoad];
UIImage *image = [UIImage imageNamed:#"logo-tag-centered.pmg"];
UIImageView *imgView = [[UIImageView alloc] initWithFrame:CGRectMake(0, 0, 0, 0)];
[imgView setImage:image];
[imgView setHidden:YES];
[self.view addSubview:imgView];
}
-(void)imageShow
{
[imgView setHidden:NO];
}
- (IBAction)changeButton:(id)sender
{
[self colorchange];
[self imageShow];
}
So I'm adding a bunch of custom UIBarButtonItems to a UIToolbar, and they all load just fine and look great, and I can see them in my UIToolbar. The only problem is, I can't perform any actions on them. In my viewDidLoad, I set up everything. Here are my .h and .m files:
.h file:
#import <UIKit/UIKit.h>
#import <MobileCoreServices/MobileCoreServices.h>
#import <QuartzCore/QuartzCore.h>
#interface PhotoEditViewController : UIViewController <UIPopoverControllerDelegate, UINavigationControllerDelegate, UIImagePickerControllerDelegate, UIGestureRecognizerDelegate> {
IBOutlet UIImageView *imageView;
}
- (IBAction)cancelEdit:(id)sender;
- (IBAction)savePhoto:(id)sender;
- (IBAction)chooseColor:(id)sender;
#property (retain) IBOutlet UIToolbar *editBar;
#property (retain) UIImageView *imageView;
#property (retain) UIImage *tempImage;
- (void) setupStache;
#end
.m file: (viewDidLoad)
#pragma mark - View lifecycle
- (void)viewDidLoad
{
[super viewDidLoad];
self.imageView.image = tempImage;
NSMutableArray *toolbarItems = [NSMutableArray arrayWithCapacity:3];
// get the filepaths of all the images
NSString *imagePath_cancel = [[NSBundle mainBundle] pathForResource:#"barBtnPhotoEditCancel" ofType:#"png"];
NSString *imagePath_save = [[NSBundle mainBundle] pathForResource:#"barBtnSavePhoto" ofType:#"png"];
NSString *imagePath_color = [[NSBundle mainBundle] pathForResource:#"barBtnChangeColor" ofType:#"png"];
// get the images
UIImage *cancelImage = [[UIImage alloc] initWithContentsOfFile:imagePath_cancel];
UIImage *saveImage = [[UIImage alloc] initWithContentsOfFile:imagePath_save];
UIImage *changeColorImage = [[UIImage alloc] initWithContentsOfFile:imagePath_color];
// set the images to the UIBarButtonItem(s)
CGRect cancelFrame = CGRectMake(0, 0, cancelImage.size.width-25, cancelImage.size.height-25);
UIButton* cancelButton = [[UIButton alloc] initWithFrame:cancelFrame];
[cancelButton setBackgroundImage:cancelImage forState:UIControlStateNormal];
[cancelButton setShowsTouchWhenHighlighted:YES];
UIBarButtonItem *cancelBarButtonItem = [[UIBarButtonItem alloc] initWithCustomView:cancelButton];
[cancelBarButtonItem setTarget:self];
[cancelBarButtonItem setAction:#selector(cancelEdit:)];
CGRect saveFrame = CGRectMake(0, 0, saveImage.size.width-25, saveImage.size.height-25);
UIButton* saveButton = [[UIButton alloc] initWithFrame:saveFrame];
[saveButton setBackgroundImage:saveImage forState:UIControlStateNormal];
[saveButton setShowsTouchWhenHighlighted:YES];
UIBarButtonItem* saveBarButtonItem = [[UIBarButtonItem alloc] initWithCustomView:saveButton];
[saveBarButtonItem setTarget:self];
[saveBarButtonItem setAction:#selector(savePhoto:)];
CGRect colorFrame = CGRectMake(0, 0, changeColorImage.size.width-25, changeColorImage.size.height-25);
UIButton* colorButton = [[UIButton alloc] initWithFrame:colorFrame];
[colorButton setBackgroundImage:changeColorImage forState:UIControlStateNormal];
[colorButton setShowsTouchWhenHighlighted:YES];
UIBarButtonItem* colorBarButtonItem = [[UIBarButtonItem alloc] initWithCustomView:colorButton];
[colorBarButtonItem setTarget:self];
[colorBarButtonItem setAction:#selector(chooseColor:)];
// add all the items
[toolbarItems addObject:cancelBarButtonItem];
[toolbarItems addObject:saveBarButtonItem];
[toolbarItems addObject:colorBarButtonItem];
[self.editBar setItems:toolbarItems animated:NO];
// release everything
[cancelBarButtonItem release];
[cancelButton release];
[saveBarButtonItem release];
[saveButton release];
[colorBarButtonItem release];
[colorButton release];
}
- (IBAction)cancelEdit:(id)sender {
NSLog(#"Pressing the cancel button");
}
- (IBAction)savePhoto:(id)sender {
NSLog(#"Pressing the save button");
}
- (IBAction)chooseColor:(id)sender {
NSLog(#"Pressing the choose color button");
}
So, here's the answer.
I was inserting a custom subview that was the size of the entire screen (320x640). It also had gestureRecognizers attached to it. Therefore, whenever I tapped that view, the gestureRecognizer responded to the attached subview, instead of the uitoolbar, or the buttons on it. Man I'm foolish. Resized the image on the UIView, and everything works fine. :) Thanks everyone for the help.
initWithCustomView - view must be button and set action on button
I have a few UIToolbars throughout my app. I want each one to have a different background. Here is an example of a Category I have:
#import "UIToolbar+NavBarAdditions.h"
#implementation UIToolbar (Addition)
- (void) drawRect:(CGRect)rect {
UIImage *barImage = [UIImage imageNamed:#"rowbg.png"];
[barImage drawInRect:rect];
}
#end
I have a few images rowbg1, rowbg2 etc etc that I want to use for other UIToolbars that are inside of my app. How can I choose which category to use for the respective toolbar?
Change a toolbar background
Using a subclass
A category changes all UIToolbar classes. If you need different toolbars, let each client be in charge of setting the image:
#interface UIBgToolbar : UIToolbar {
#private
UIImage *_background;
}
#end
#implementation UIBgToolbar
- (id)initWithFrame:(CGRect)aRect imagen:(UIImage*)image {
if (self = [super initWithFrame:aRect]){
_background = [image retain];
}
return self;
}
- (void) drawRect:(CGRect)rect {
UIImage *barImage = _background;
[barImage drawInRect:rect];
}
-(void)dealloc {
[_background release];
[super dealloc];
}
#end
Usage:
UIImage *bg = [UIImage imageNamed:#"bar_bottom.png"];
// 416 = 480 - status bar (20) - navigation bar (44)
CGRect rect = CGRectMake(0, 416-bg.size.height, bg.size.width, bg.size.height);
UIBgToolbar *toolbar = [[UIBgToolbar alloc] initWithFrame:rect imagen:bg];
[self.view addSubview:toolbar];
[toolbar release];
Using a subview
This is an alternative way that adds a subview and doesn't need subclasses or categories:
UIImage *bg = [UIImage imageNamed:#"bar_bottom.png"];
// 416 = 480 - status bar (20) - navigation bar (44)
CGRect rect = CGRectMake(0, 416-bg.size.height, bg.size.width, bg.size.height);
UIToolbar *toolbar = [[UIToolbar alloc] initWithFrame:rect];
UIImageView *background = [[[UIImageView alloc] initWithImage:bg] autorelease];
background.frame = toolbar.bounds;
background.autoresizingMask = UIViewAutoresizingFlexibleWidth;
BOOL isIOS5 = [[[UIDevice currentDevice] systemVersion] intValue] >= 5;
toolbar insertSubview:background atIndex: (isIOS5 ? 1 : 0)];
[self.view addSubview:toolbar];
[toolbar release];
Making the background transparent.
Don't use this unless you really need a transparent background.
#interface UITransparentToolBar : UIToolbar
#end
#implementation UITransparentToolBar
- (void)drawRect:(CGRect)rect {
[[UIColor clearColor] set];
CGContextFillRect(UIGraphicsGetCurrentContext(), rect);
}
#end
Usage:
// create the toolbar
UIImage *bg = [UIImage imageNamed:#"bar_bottom.png"];
// 416 = 480 - status bar (20) - navigation bar (44)
CGRect rect = CGRectMake(0, 416-bg.size.height, bg.size.width, bg.size.height);
UIBgToolbar *toolbar = [[UIBgToolbar alloc] initWithFrame:rect];
// add the background
// self.backgroundColor = [UIColor clearColor];
UIImageView *background = [[UIImageView alloc] initWithImage:bg];
background.frame = toolbar.bounds;
background.autoresizingMask = UIViewAutoresizingFlexibleWidth;
BOOL isIOS5 = [[[UIDevice currentDevice] systemVersion] intValue] >= 5;
[toolbar insertSubview:background atIndex: (isIOS5 ? 1 : 0)];
[self.view addSubview:toolbar];
[toolbar release];
Change a navigation bar
Navigation bar background
Use Noah's code in a category.
Using a subclass is also possible:
Create a UINavigationToolbar subclass containing the drawRect method from Noah's answer. - Select your MainWindow.XIB, select "Navigation Bar", press ⌥⌘3 to (show Identity Inspector), and change the class to the class you just created.
Also while in IB, press ⌥⌘4 (show Attributes Inspector) and set a number in the field Tag. If you look at Noah's code, that number decides which image to use.
Navigation bar toolbar background
Same thing as for a normal toolbar but using a category because the navigation toolbar is read-only:
// UIToolbar.h
#interface UIToolbar (Transparency)
- (void)drawRect:(CGRect)rect;
#end
// UIToolbar.m
#import "TransparentToolbar.h"
#implementation UIToolbar (Transparency)
- (void)drawRect:(CGRect)rect {
[[UIColor clearColor] set];
CGContextFillRect(UIGraphicsGetCurrentContext(), rect);
}
#end
Usage:
// bar_bottom_bumped.png is a toolbar image with transparency
UIImage *bg = [UIImage imageNamed:#"bar_bottom_bumped.png"];
UIImageView *background = [[UIImageView alloc] initWithImage:bg];
background.frame = self.navigationController.toolbar.bounds;
background.autoresizingMask = UIViewAutoresizingFlexibleWidth;
BOOL isIOS5 = [[[UIDevice currentDevice] systemVersion] intValue] >= 5;
self.navigationController.toolbar.backgroundColor = [UIColor clearColor];
[self.navigationController.toolbar insertSubview:background atIndex: (isIOS5 ? 1 : 0)];
If you’re creating the toolbars yourself—in IB or through code—then Jano’s solution is mostly right, though I disagree with the idea of making it transparent: you should avoid doing unnecessary blending. If you need to replace the toolbars created by a navigation controller, though, you do need to use a category rather than subclassing. You can use your existing implementation; you just need to set a different tag on each of the toolbars you want to have a different appearance, then check that value in your -drawRect:. In other words, your view controller should have something like this:
- (void)viewWillAppear:(BOOL)animated
{
[super viewWillAppear:animated];
UIToolbar *toolbar = self.navigationController.toolbar;
toolbar.tag = 3; // different value for each controller, or however you want to choose the toolbar
[toolbar setNeedsDisplay];
}
and your toolbar category should have something like this:
- (void)drawRect:(CGRect)r
{
UIImage *barImage = nil;
switch(self.tag)
{
case 1:
barImage = [UIImage imageNamed:#"rowbg.png"];
break;
case 3:
barImage = [UIImage imageNamed:#"something else.png"];
break;
}
[barImage drawInRect:self.bounds];
}
You should use subclassing instead of categories.
What I Want: A border indicating if a UIButton is selected or not.
Background: I've got some UIButtons using transparent images, not text. These are toggle buttons (i.e. can be on or off).
Problem: The UIButton class gives users no indication of whether a button is selected or not unless you change something else about the button. Since the image doesn't change with the state, I'd need two of every image, one normal, one selected and set one for each state of the button. This is annoying. I thought instead I'd change the background image, but this removes the pretty border on the button, I just get a rectangle of my background image, yuck.
Possible solutions I don't like:
1) Create a background that matches the UIButton border and use that for selected. I don't like this because they wont match perfectly and I'm picky.
2) Create two images for each button, essentially identical but with a different background. This seems like unnecessary work, and since this problem is coming up repeatedly, I want a solution for the future as well.
I hope somebody's figured out a decent solution to this by now. Thanks in advance.
Since UIButton has two image layers, an image and a background image, I think you could accomplish what you want by using just two background images for all your buttons. One image shows a border and the other does not. Swap the backgrounds out when the control state changed.
//
// TabBarSingleton.h
#import <Foundation/Foundation.h>
#interface TabBarSingleton : UITabBarController <UITabBarControllerDelegate>{
NSRecursiveLock *barLock;
UIButton *Button;
UIButton *favoriteButton;
}
#property(nonatomic, retain) UIButton *Button;
#property(nonatomic, retain) UIButton *favoriteButton;
- (void) ButtonPressed;
- (void) favoriteButtonPressed;
#end
///////////////////////////////////
If you want the the borders only, then you have only one choice of using two images for the two states otherwise if your purpose is to differentiate between two states then you can do it by changing alpha a little bit of the selected button this will give the effect like toggle buttons, you can also disable the selected button and enable it again when the other button is pressed.
Hope this will give you a fair idea.
//
// TabBarSingleton.m
// Created by ArunDhwaj on 9/7/10.
// Copyright 2010 __MyCompanyName__. All rights reserved.
//
#import "TabBarSingleton.h"
#implementation TabBarSingleton
#synthesize Button, favoriteButton;
- (id) init
{
if (self = [super initWithNibName: nil bundle: nil])
{
barLock = [[NSRecursiveLock alloc] init];
}
self.delegate = self;
return self;
}
+ (TabBarSingleton *) defaultBar
{
}
- (void)viewDidLoad
{
NSLog(#"TabBarSingleton: viewDidLoad");
//Hiding TabBar
self.tabBar.hidden = YES;
//Creating a UIView, its frame is same as tabBar frme
CGRect tabbarFrame = self.tabBar.frame;
UIView* customTabbarView = [[UIView alloc] initWithFrame:tabbarFrame];
UIImageView *newsFeedImg = [[UIImageView alloc] initWithImage:[UIImage imageNamed:#"newsfeeds_normal.png"]];
newsFeedImg.frame = CGRectOffset(newsFeedImg.frame, 0, 1);
Button = [UIButton buttonWithType:UIButtonTypeCustom];
[Button setFrame:newsFeedImg.frame];
[Button setBackgroundImage:newsFeedImg.image forState:UIControlStateNormal];
[Button setBackgroundImage:[UIImage imageNamed:#"newsfeeds_active.png"] forState:UIControlStateHighlighted];
[Button addTarget:self action:#selector(newsFeedsButtonPressed) forControlEvents:UIControlEventTouchUpInside];
[customTabbarView addSubview:Button];
//[newsFeedImg release];
CGRect newsFeedFrame = newsFeedImg.frame;
UIImageView *favoriteImg = [[UIImageView alloc] initWithImage:[UIImage imageNamed:#"favorites_normal.png"]];
favoriteImg.frame = CGRectMake(newsFeedFrame.size.width, newsFeedFrame.origin.y, newsFeedFrame.size.width, newsFeedFrame.size.height);
favoriteButton = [UIButton buttonWithType:UIButtonTypeCustom];
[favoriteButton setFrame:favoriteImg.frame];
[favoriteButton setBackgroundImage:favoriteImg.image forState:UIControlStateNormal];
[favoriteButton setBackgroundImage:[UIImage imageNamed:#"favorites_active.png"] forState:UIControlStateHighlighted];
[favoriteButton addTarget:self action:#selector(favoriteButtonPressed) forControlEvents:UIControlEventTouchUpInside];
[customTabbarView addSubview: favoriteButton];
//[favoriteImg release];
[self.view addSubview:customTabbarView ];
[self newsFeedsButtonPressed];
}
- (void) newsFeedsButtonPressed
{
NSLog(#"TabBarSingleton: newsFeedsButtonPressed");
self.selectedIndex = 0;
//Keeping Highlighted newsFeed tab
UIImageView *newsFeedImg = [[UIImageView alloc] initWithImage:[UIImage imageNamed:#"newsfeeds_active.png"]];
[Button setImage: newsFeedImg.image forState:UIControlStateNormal];
//Keeping normal others tab icons
UIImageView *favoriteImg = [[UIImageView alloc] initWithImage:[UIImage imageNamed:#"favorites_normal.png"]];
[favoriteButton setImage: favoriteImg.image forState:UIControlStateNormal];
}
- (void) favoriteButtonPressed
{
NSLog(#"TabBarSingleton: favoriteButtonPressed");
self.selectedIndex = 1;
//Keeping Highlighted newsFeed tab
UIImageView *newsFeedImg = [[UIImageView alloc] initWithImage:[UIImage imageNamed:#"newsfeeds_normal.png"]];
[Button setImage: newsFeedImg.image forState:UIControlStateNormal];
//Keeping normal others tab icons
UIImageView *favoriteImg = [[UIImageView alloc] initWithImage:[UIImage imageNamed:#"favorites_active.png"]];
[favoriteButton setImage: favoriteImg.image forState:UIControlStateNormal];
#pragma mark UITabBarControllerDelegate
- (BOOL)tabBarController:(UITabBarController *)tabBarController shouldSelectViewController:(UIViewController *)viewController
{
NSLog(#"TabBarSingleton: shouldSelectViewController");
return YES;
}
- (void)tabBarController:(UITabBarController *)tabBarController didSelectViewController:(UIViewController *)viewController
{
NSLog(#"TabBarSingleton: didSelectViewController");
}
- (void) dealloc
{
//[barLock release];
[super dealloc];
}
#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;
}