Customizing UINavigationBar as in Fox news iPhone app - iphone

How can the UINavigationBar customizations be done? Is it using subclassing or categories?
I am interested in 2 aspects:
Adding an image to the NavBar (like the FOXNEWS logo)
Customizing the back button to "Shows". (the back button usually takes the title of the previous view in the stack, but there is no title in previous view.)
Thanks in advance for any help

For the Fox News app it looks like they just set the tint color of the navigation bar. As for the Fox News logo, it's probably just an image view on the title view of the navigation bar. This code goes into a view controller's viewDidLoad method:
[self.navigationController.navigationBar setTintColor:/* Custom color here */];
UIImageView *logoView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:#"logo"]];
[self.navigationItem setTitleView:logoView];
[logoView release];
To customize the back button you need to place this in the viewDidLoad method of the previous view controller (i.e. the one that this button leads back to):
UIBarButtonItem *backButton = [[UIBarButtonItem alloc] initWithTitle:#"Shows"
style:UIBarButtonItemStyleBordered target:nil action:nil];
[self.navigationItem setBackBarButtonItem:backButton];
[backButton release];
If you want to use a totally custom background image for your application's navigation bar, you need to create a custom UINavigationBar category and draw the image within its drawRect: method. Something like this:
#implementation UINavigationBar (UINavigationBarBackgroundImage)
- (void)drawRect:(CGRect)rect
{
[[UIImage imageNamed:#"navigation-bar"] drawInRect:rect];
// Optionally you can set the tintColor here to go with the background
}
#end

adding image to navigation bar use this code
- (void)drawRect:(CGRect)rect {
UIColor *color = [UIColor blackColor]; //this use to set button color in FoxNew Site //button color
UIImage *img = [UIImage imageNamed: #"ImageName"];
[img drawInRect:CGRectMake(0, 0, self.frame.size.width, self.frame.size.height)];
self.tintColor = color;
}
create category for UINavigationBar
#implementation UINavigationBar (UINavigationBarCategory)
- (void)drawRect:(CGRect)rect {
}
#end

Related

Hide Navigation Bar but not the back button

i hide my navigation using:
[self.navigationController setNavigationBarHidden:YES animated:YES];
But i need to not hide the back button, it's Possible?
nevan king is right but you can simply change the background image of the navigation bar or set it to nil. If you set it to nil or provide a transparent BG-image you would achieve the effect you need.
For iOS >= 5.0 you could simply set the appearance:
if([navigationBar respondsToSelector:#selector(setBackgroundImage:forBarMetrics:)]) // needed if iOS older than 5.0 is also supported
[navigationBar setBackgroundImage:nil forBarMetrics:UIBarMetricsDefault];
You can do that where ever you have a pointer to your navigation bar. E.g. inside of the viewDidLoad method of your ViewController.
For older iOS version you need a workaround by making a category of UINavigationBar and overwrite the drawRect method:
#implementation UINavigationBar (BackgroundImage)
- (void)drawRect:(CGRect)rect {
UIImage *image = [UIImage imageNamed: #""];
[image drawInRect:CGRectMake(0, 0, self.frame.size.width, self.frame.size.height)];
}
#end
Both methods are compatible if you want to support all iOS versions.
Thus you should keep in mind, that the back button uses the same background image. So you will need to make a custom one.
UIImage *bgImageNormal = [UIImage imageNamed:#"backButtonImage.png"];
UIButton *button = [UIButton buttonWithType:UIButtonTypeCustom];
[button setBackgroundImage: bgImageNormal forState:UIControlStateNormal];
button.frame= CGRectMake(0.0, 0.0, bgImageNormal.size.width, bgImageNormal.size.height);
[button addTarget:self action:#selector(navigationBarBackButtonTouchUpInside:) forControlEvents:UIControlEventTouchUpInside]; // your action method here
UIBarButtonItem *closeButton = [[UIBarButtonItem alloc] initWithCustomView:button];
self.navigationItem.leftBarButtonItem = closeButton;
[closeButton release];
This code needs to be implemented for each ViewController you are pushing to your navigation bar. A good place for it is also inside the viewDidLoad method.
The back button is created by the navigation bar and always part of it, so it's not possible. You could hide and re-show the navigation bar when your user touches on the screen (this is what the Photos app does when you look at a single photo) or create a button and have it permanently on the top left of the screen. You could also make the navigation bar partly transparent so that the content underneath shows up.

custom UINavigationController and UIBarbuttonItem

i have the following code to customize UINavigationController :
#implementation UINavigationBar (UINavigationBarCategory)
- (void)drawRect:(CGRect)rect
{
UIImage *image = [UIImage imageNamed:#"NavBar.png"];
[image drawInRect:rect];
}
this works great but i want also in the same time change the background of items in navigationbar like (back and refresh ...)to the same background of navigationbar
Have you tried overriding the drawRect methods for UIBarButtonItem? Also, you can always set the customView of a UIBarButtonItem to a UIButton and set the background of the UIButton to the same as the one of the UINavigationBar.

How to wire custom UINavigationBar to UINavigationController

So I've been researching on how to have an image in UINavigationBar and the safest way to do it that works for iOS 4 and iOS 5 is via subclassing the UINavigationBar, so I had:
#interface CustomNavigationBar : UINavigationBar
#end
#implementation CustomNavigationBar
-(void) drawRect:(CGRect)rect
{
UIImage *image = [UIImage imageNamed: #"myNavBarImage"];
[image drawInRect:CGRectMake(0, 0, self.frame.size.width, self.frame.size.height)];
}
#end
Now say I wanted to hook up ProfileViewController to have this custom UINavigationBar, how do I do that? Here's how I set ProfileViewController.
ProfileViewController *profile = [[ProfileViewController alloc] init];
localNavigationController = [[UINavigationController alloc] initWithRootViewController:profile];
[localControllersArray addObject:localNavigationController];
[localNavigationController release];
[profile release];
Any idea on how to wire this up? I've read that this has to be done via IB by changing the class of my UINavigationBar to the class that I just created. However, I don't have any UINavigationBar in my xib file, as it is created programatically via the UINavigationController.
One other issue also is that if I wanted to have a dynamic image that I can change/specify to the UINavigationBar, how do I do this? As of now it is hard wired that the UINavigationbar will have an image called myNavBarImage, but what if I wanted to set it to something else so I don't have to create 10 custom UINavigationBar, I somehow wanted to set the image name.
There is a solution similar to yours but uses categories instead of subclassing:
http://www.developers-life.com/custom-uinavigationbar-with-image-and-back-button.html
However, you have other choices that will make it easier for you such as adding an image as a subview to UINavigationBar. It is a safe way to do it,and I used it in a previous project which was approved.
My favorite way to do it is hiding the navigation bar and adding an imageView with buttons to have full control on how the navigation bar looks like (I especially use it when I need to add custom buttons as well).
Edit (Code to use for the second issue):
At viewDidLoad
UIImageView *imageview = [[UIImageView alloc] initWithImage: [UIImage imageNamed: #"image1.png"]];
[self.navigationController.navigationBar addSubview:imageview];
[self.navigationController.navigationBar sendSubviewToBack:imageview];
[imageview release];
At the method that changes the image:
-(void) changeNavigationBarImage: (NSString *) imageName{
for (UIView *view in self.navigationController.navigationBar.subviews) {
if ([view isKindOfClass:[UIImageView class]])
{
[(UIImageView *)view setImage:[UIImage imageNamed:imageName]];
break;
}
}
}
You can call this method when you want to change the image (i.e. button or timer)

Background image for navigation view

I am having problems with properly displaying background image of navigation view.
Here is the pic:
Here is the code:
- (id)initWithStyle:(UITableViewStyle)style {
if (self = [super initWithStyle:style]) {
UIImage *image = [UIImage imageNamed: #"bg_table_active.png"];
UIImageView *imageview = [[UIImageView alloc] initWithImage: image];
UIBarButtonItem *addButton = [[UIBarButtonItem alloc]
initWithTitle:NSLocalizedString(#"Settings", #"")
style:UIBarButtonItemStyleDone
target:self
action:#selector(GoToSettings)];
self.navigationItem.titleView = imageview;
self.navigationItem.rightBarButtonItem = addButton;
self.navigationItem.hidesBackButton = TRUE;
}
return self;
}
How can I make the picture stretch to the whole navigation view?
I do exactly this in my app. Within AppDelegate I have this code:
#implementation UINavigationBar (CustomImage)
- (void)drawRect:(CGRect)rect
{
UIImage *image = [UIImage imageNamed: #"custom_nav_bar.png"];
[image drawInRect:CGRectMake(0, 0, self.frame.size.width, self.frame.size.height)];
}
#end
I modified Mike Rundle's version so that the a custom image can be set if necessary. I also merged in 40lb-suit-of-bees suggested changes. initImageDictionary needs to be called during initialisation:
//UINavigationBar+CustomImage.h
#import <Foundation/Foundation.h>
#interface UINavigationBar(CustomImage)
+ (void) initImageDictionary;
- (void) drawRect:(CGRect)rect;
- (void) setImage:(UIImage*)image;
#end
//UINavigationBar+CustomImage.m
#import "UINavigationBar+CustomImage.h"
//Global dictionary for recording background image
static NSMutableDictionary *navigationBarImages = NULL;
#implementation UINavigationBar(CustomImage)
//Overrider to draw a custom image
+ (void)initImageDictionary
{
if(navigationBarImages==NULL){
navigationBarImages=[[NSMutableDictionary alloc] init];
}
}
- (void)drawRect:(CGRect)rect
{
NSString *imageName=[navigationBarImages objectForKey:[NSValue valueWithNonretainedObject: self]];
if (imageName==nil) {
imageName=#"header_bg.png";
}
UIImage *image = [UIImage imageNamed: imageName];
[image drawInRect:CGRectMake(0, 0, self.frame.size.width, self.frame.size.height)];
}
//Allow the setting of an image for the navigation bar
- (void)setImage:(UIImage*)image
{
[navigationBarImages setObject:image forKey:[NSValue valueWithNonretainedObject: self]];
}
#end
Mike Rundle and Casebash's code is great. I used [NSValue valueWithNonretainedObject:self] to avoid the copyWithZone error. Wrapping self in an NSValue object allows it to be copied into the navigationBarImages dictionary.
- (void)drawRect:(CGRect)rect
{
NSString *imageName=[navigationBarImages objectForKey:[NSValue valueWithNonretainedObject:self]];
...}
- (void)setImage:(NSString*)image
{
[navigationBarImages setObject:image forKey:[NSValue valueWithNonretainedObject:self]];
}
http://foobarpig.com/iphone/uinavigationbar-with-solid-color-or-image-background.html
Hope it helps..
You can use this also
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];
}
`
http://developer.apple.com/iphone/library/featuredarticles/ViewControllerPGforiPhoneOS/UsingNavigationControllers/UsingNavigationControllers.html#//apple_ref/doc/uid/TP40007457-CH7
Looking at Figure 1 in that link - would it be better to set the backgroundImage on your navigationbar not your navigationitem?
UIImage *image = [UIImage imageNamed: #"navigator.png"];
[_homeNavigationController.navigationBar setBackgroundImage:image forBarMetrics:UIBarMetricsDefault];
Unfortunately, there is no support for using custom background images in a navigation bar in iPhone OS 3.0 or any previous versions. The only way to customize the appearance is to set the style and tint color. Not perfect, I know.
In your code you are trying to stretch the title view of the navigation bar to "go under" the right button. But this is impossible since the three views of a navigation bar (back button, title, and right button) are supposed to be in the same layer and are adjusted to not overlap. This is a feature.
I know there are a number of third-party apps that change the background image but they are "hacking" the system and are using unsupported private API:s or assumptions of the internal data structures of the navigation bar. These programs will most likely fail (crash or display incorrectly) in future versions of iPhone OS.
You most likely don't want to mess with this. Accept the fact that that you cannot (yet) have a custom background image in navigation bars. It hurts, I know. But if you hack the system and your app fails in a future versions of the OS, Apple will pull the app from the app store and you will lose all revenue until you have changed the app. It's your call...

how to display an image in the navigation bar of an iPhone application?

how to display an image in the navigation bar of an iPhone application? (say, right after the title)
Here's how to have the image centered in the NavBar.
UIImage *image = [UIImage imageNamed: #"NavBarImage.png"];
UIImageView *imageView = [[UIImageView alloc] initWithImage: image];
self.navigationItem.titleView = imageView;
[imageView release];
This code is actually contained with the Apple source for the NavBar and can be found at the iPhone Developer Center at Apple.
The source shows you various ways to manipulate both the StatusBar & NavBar.
I haven't tested this but as UINavigationBar is a view you can add subViews to it.
UIImage* myImage = [UIImage imageNamed:#"Myimage.png"];
UIImageView* myImageView = [[UIImageView alloc] initWithImage:myImage];
myImageView.frame.origin.x = 30.0; // You will have to find suitable values for the origin
myImageView.frame.origin.y = 5.0;
[myTabbar addSubView:myImageView];
[myImageView release];
You can use things like the backItem property to calculate the position of your image view.
If you want the image at the right of the nav bar, you can define it as a custom button with no action when presed, like this
UIButton* fakeButton = (UIButton *) [[UIImageView alloc] initWithImage:[UIImage imageNamed:#"yourimage.png"]];
UIBarButtonItem *fakeButtonItem = [[UIBarButtonItem alloc] initWithCustomView:fakeButton];
self.navigationItem.rightBarButtonItem = fakeButtonItem;
[fakeButtonItem release];
[fakeButton release];
Simply Place that code in - (void)viewWillAppear:(BOOL)animated; so it'll work fine
and add one image having size 320x40 named Top Bar
UIImage *image = [UIImage imageNamed: #"TopBar.png"];
[self.navigationController.navigationBar setBackgroundImage:image forBarMetrics:UIBarMetricsDefault];
the navigation bar has a property called title view - set this to the image you like. Since the titleView overwrites the title of the nav bar you have to include the desired title in the image file. Still set the title to what you want so it appears on the back button when you push a view Controller
I encountered the same problem.Found out the best solution
[self.navigationController.navigationBar setBackgroundImage:[UIImage imageNamed:#"background_image.png"] forBarMetrics:UIBarMetricsDefault];
Hope this would help....
Just write your own navigation bar. Therefore you have to disable the Navigation Bar fist:
Disable the top bar in the interface builder by selecting your Navigation Controller in
your Storyboard: Attributes Inspector -> Simulated Metrics -> Top Bar: select None
Afterwards you can add any HeaderView you like...
UIView *headerView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, sFrame.size.width, 100)];
UIColor *background = [[UIColor alloc] initWithPatternImage:[UIImage imageNamed:#"header_image.png"]];
self.headerView.backgroundColor = background;
// ...add buttons and labels
[self.view addSubview:headerView];