Possible Duplicate:
How to add background image on iphone Navigation bar ?
iOS - How did the NY Times do this custom top navigation bar styling?
And for that matter, the bottom one?
Possible Duplicate:
How to add background image on iphone Navigation bar ?
iOS - How did the NY Times do this custom top navigation bar styling?
And for that matter, the bottom one?
EDIT: This is outdated; for iOS5 there's a much better answer below, by @Jenox.
Completely custom styling for Navigation Bars is surprisingly difficult. The best writeup I know of is this one by Sebastian Celis: http://sebastiancelis.com/2009/12/21/adding-background-image-uinavigationbar/
This doesn't override drawRect, and includes a good explanation why that's a good thing. Also note you don't have to follow his tutorial. You can download the complete code here: https://github.com/scelis/ExampleNavBarBackground
-drawRect:
is an idiotically stupid idea. Don't do it; you're screwing with code you don't own, and your code will break in the future. Use a subclass instead. THIS IS WHY SUBCLASSING EXISTS. –
Watereddown UINavigationController
s navigationBar
is readonly you could not display your subclass in a navigation controller. After all, why should swizzling -drawRect: break, when you do 'call super' as a subclass would? –
Fryer UINavigationBar
with your subclass while decoding using -[NSKeyedUnarchiver setClass:forClassName:
. –
Fideism drawRect:
was idiotically stupid. It is idiotically stupid -- but so is any undocumented trickery. Replacing drawRect:
worked prior to iOS 4, and the "proper" way using UIAppearance
didn't. So replacing -drawRect:
in any way may have been idiotically stupid by not being future-proof, but it surely is past-proof. And using UIAppearance
is the only future-proof way, anyway. :-) –
Fideism @ludwigschubert's solution does however not work on iOS 5. Neither does overriding -drawRect:
, because it isn't even called.
As of iOS 5, a navigation bar consist of a UINavigationBarBackground
and a UINavigationItemView
. There are two other ways of getting it work.
Insert your custom image view at index 1 instead of 0. This makes it appear above the native background image while staying below the buttons.
Make use of iOS 5's UIAppearance protocol. You can either set the background image for all
[[UINavigationBar appearance] setBackgroundImage:myImage forBarMetrics:UIBarMetricsDefault]
or for just one navigation bar:
[navigationController.navigationBar setBackgroundImage:myImage forBarMetrics:UIBarMetricsDefault]
Make sure to provide two images (UIBarMetricsDefault & UIBarMetricsLandscapePhone) when developing an iPhone app for both portrait and landscape.
EDIT: This is outdated; for iOS5 there's a much better answer below, by @Jenox.
Completely custom styling for Navigation Bars is surprisingly difficult. The best writeup I know of is this one by Sebastian Celis: http://sebastiancelis.com/2009/12/21/adding-background-image-uinavigationbar/
This doesn't override drawRect, and includes a good explanation why that's a good thing. Also note you don't have to follow his tutorial. You can download the complete code here: https://github.com/scelis/ExampleNavBarBackground
-drawRect:
is an idiotically stupid idea. Don't do it; you're screwing with code you don't own, and your code will break in the future. Use a subclass instead. THIS IS WHY SUBCLASSING EXISTS. –
Watereddown UINavigationController
s navigationBar
is readonly you could not display your subclass in a navigation controller. After all, why should swizzling -drawRect: break, when you do 'call super' as a subclass would? –
Fryer UINavigationBar
with your subclass while decoding using -[NSKeyedUnarchiver setClass:forClassName:
. –
Fideism drawRect:
was idiotically stupid. It is idiotically stupid -- but so is any undocumented trickery. Replacing drawRect:
worked prior to iOS 4, and the "proper" way using UIAppearance
didn't. So replacing -drawRect:
in any way may have been idiotically stupid by not being future-proof, but it surely is past-proof. And using UIAppearance
is the only future-proof way, anyway. :-) –
Fideism Just to add to the answer given by @Jenox, if you want to support both iOS 4.xx and iOS 5.xx devices (i.e. your DeploymentTarget is 4.xx), you must be careful in wrapping the call to the appearance proxy by checking at runtime if the 'appearance' selector is present or not.
You can do so by:
//Customize the look of the UINavBar for iOS5 devices
if ([[UINavigationBar class]respondsToSelector:@selector(appearance)]) {
[[UINavigationBar appearance] setBackgroundImage:[UIImage imageNamed:@"NavigationBar.png"] forBarMetrics:UIBarMetricsDefault];
}
You should also leave the iOS 4.xx workaround that you may have implemented. If you have implemented the 'drawRect' workaround for iOS 4.xx devices, as mentioned by @ludwigschubert, you should leave that in:
@implementation UINavigationBar (BackgroundImage)
//This overridden implementation will patch up the NavBar with a custom Image instead of the title
- (void)drawRect:(CGRect)rect {
UIImage *image = [UIImage imageNamed: @"NavigationBar.png"];
[image drawInRect:CGRectMake(0, 0, self.frame.size.width, self.frame.size.height)];
}
@end
This will get the NavBar look the same in both iOS 4 and iOS 5 devices.
Copy this into viewDidLoad. It will check for iOS 5 and use the preferred method, otherwise it will add a subview to the navBar for iOS versions < 5.0. This will work provided that your custom background image has no transparencies.
float version = [[[UIDevice currentDevice] systemVersion] floatValue];
NSLog(@"%f",version);
UIImage *backgroundImage = [UIImage imageNamed:@"myBackgroundImage.png"];
if (version >= 5.0) {
[self.navigationController.navigationBar setBackgroundImage:backgroundImage forBarMetrics:UIBarMetricsDefault];
}
else
{
[self.navigationController.navigationBar insertSubview:[[[UIImageView alloc] initWithImage:backgroundImage] autorelease] atIndex:1];
}
You can just create a category and create a custom method to add any view you want - images,buttons,sliders. Foe example, here is the code that i use - it adds custom backgroundimage,backButton and Label.
@interface UINavigationBar (NavigationBar)
-(void)setBarForCard;
@end
@implementation UINavigationBar (NavigationBar)
-(void)setBarForCard
{
UIImageView *aTabBarBackground = [[UIImageView alloc]initWithImage:[UIImage imageNamed:@"BarImage"]];
aTabBarBackground.frame = CGRectMake(0,0,self.frame.size.width,44);
[self addSubview:aTabBarBackground];
[self sendSubviewToBack:aTabBarBackground];
[aTabBarBackground release];
UIButton *backBtn = [UIButton buttonWithType:UIButtonTypeCustom];
backBtn.frame =CGRectMake(10, 8, 60, 30);
[backBtn addTarget:self action:@selector(back:)forControlEvents:UIControlEventTouchUpInside];
[backBtn setImage:[UIImage imageNamed: @"Back"] forState:UIControlStateNormal];
[self addSubview:backBtn];
UILabel *calendar = [[UILabel alloc]init];
calendar.frame = CGRectMake(105, 13, 109, 21);
calendar.text = @"Calendar"
calendar.textColor = [UIColor whiteColor];
calendar.textAlignment = UITextAlignmentCenter;
calendar.shadowColor = [UIColor grayColor];
calendar.shadowOffset = CGSizeMake(0, -1);
calendar.font = [UIFont fontWithName:@"HelveticaNeue-Bold" size:20];
calendar.backgroundColor = [UIColor clearColor];
[self addSubview:calendar];
}
And then, in any view controller, you can change your navigationbar by calling [self.navigationController.navigationBar setBarForCard];
This works both in IOS 4 and IOS 5
This is a better way for iOS 5
if ([self.navigationController.navigationBar respondsToSelector:@selector(setBackgroundImage:forBarMetrics:)] ) {
UIImage *image = [UIImage imageNamed:@"navBarImg.png"];
[self.navigationController.navigationBar setBackgroundImage:image forBarMetrics:UIBarMetricsDefault];
}
you can change the tint color of navigation bar to change its color and also you can use an image in navigation bar view. For bottom bar i think they are using a view with three custom buttons on it.
© 2022 - 2024 — McMap. All rights reserved.