Issue with UINavigationBar title alignment - iphone

I have an issue changing the font for the Title in my navigation controller.
Here is my code (from my subclass of UINavigationController):
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view.
NSDictionary * attributes = #{UITextAttributeTextColor :[UIColor whiteColor],
UITextAttributeFont :[UIFont fontWithName:#"Blanch" size:50],
};
self.navigationBar.titleTextAttributes = attributes;
CGFloat verticalOffset = -8;
[[UINavigationBar appearance] setTitleVerticalPositionAdjustment:verticalOffset forBarMetrics:UIBarMetricsDefault];
UIImage *image = [UIImage imageNamed:NAVBAR_IMAGE];
[self.navigationBar setBackgroundImage:image forBarMetrics:UIBarMetricsDefault];
}
This is what it looks like:
If I comment out the line setting the font this is what it looks like (as expected with the vertical offset):
The only reason the vertical offset is there is that I thought it might have solved the problem. I don't need it and it is commented out now, but it does NOT change the output - it still looks the same just lower on the NavBar.
Any ideas how to solve this? I think it may be that the custom font has a lot of line-spacing
which I guess could be the problem.
I have been trying to find a way to change the origin/height/baseline alignment of the title but can't see a way to do any of these.
Any idea how to solve this problem ?

Create a container UIView which is the same width as your label, and height of UINavigationBar (around 46 pixels?). Set clipsToBounds on this container view to YES. Now add your label to this container view, and make the container view the titleView.

Setting Navigationbar image for ios5
if ([self.navigationController.navigationBar respondsToSelector:#selector( setBackgroundImage:forBarMetrics:)]){
[self.navigationController.navigationBar setBackgroundImage:[UIImage imageNamed:#"YOUR_NAVIGATION_BAR_IMAGE"] forBarMetrics:UIBarMetricsDefault];
}
Setting Navigationbar image for ios6
if([[UINavigationBar appearance] respondsToSelector:#selector( setBackgroundImage:forBarMetrics:)]){
[[UINavigationBar appearance] setBackgroundImage:[UIImage imageNamed:#"YOUR_NAVIGATION_BAR_IMAGE"] forBarMetrics:UIBarMetricsDefault];
after than create label in center on your navigation bar center with your title.

Related

ios7 UINavigationBar backgroundImage is set upside down

I am trying to set the UINavigationBar background image:
I added in AppDelegate: (please note that it's one image)
[[UIApplication sharedApplication] setStatusBarStyle:UIStatusBarStyleLightContent];
[[UINavigationBar appearance] setBackgroundImage:[UIImage imageNamed:#"general-top_bar_with_status.png"] forBarMetrics:UIBarMetricsDefault];
Since I don't need translucent, in the ViewController in ViewDidLoad I added:
self.navigationController.navigationBar.translucent = NO;
This is the image:
Unfortunately this is what I get:
As you can see, the image is upsite down.
What is wrong?
In storyboard, I set a place for TopBar - Opaque navigation bar
For iOS 7 you have to use 320x64 size navigation bar image
make picture 2X Size. with name mynavbar#2x.png
Nav bar is Taking size of its self + status bar size. You may create only navbar size
640X88
or 640X128 for navbar + status bar
Then
[self.navigationController.navigationBar setBackgroundImage:[UIImage imageNamed:#"mynavbar.png"] forBarMetrics:UIBarMetricsDefault];

Custom UINavigationBar Height Issues

So I'm building an iOS application, and I customized my UINavigationBar to be taller than the default size. A couple problems have arisen, however.
My content acts as if the UINavigationBar is of the default height. This results in any views at y=0 to actually be hidden, or partially hidden, by my taller UINavigationBar. I have to manually place views the correct offset downward, which isn't a terribly huge issue, but I'm curious as to whether anyone has found a way to fix this. Essentially my UINavigationBar is being treated as a normal one with a larger background image.
Any views/buttons in my UINavigationBar are not tappable if the portion being tapped is below the typical 44px bottom of a normal UINavigationBar. Anything within the normal range works fine, but below that 44px mark it doesn't register. Again, it's as if my UINavigationBar is being treated by the application as one with a normal height but a large background image. This is a much more critical issue that I really need to resolve.
Here is the code that modifies my UINavigationBar:
[[UINavigationBar appearance] setBackgroundImage:[UIImage imageNamed:#"navBarBackground_iPhone.png"] forBarMetrics:UIBarMetricsDefault];
[self.navController.navigationBar setBackgroundColor:[UIColor whiteColor]];
[self.navController.navigationBar setFrame:CGRectMake(0, 0, self.frame.size.width, 72)];
This is performed in my main window's -makeKeyAndVisible after my UINavigationController is allocated and initialized with a root view controller. The background image is 320px wide and 72px tall (double for the #2x version).
As you can see, I attempt to set the UINavigationBar's height here, after this portion of code it doesn't seem to stick. It reverts to 44px.
I've tried unsuccessfully to subclass UINavigationBar. Any help is greatly appreciated.
Try to subclass UINavigationBar and override the following method:
- (void)drawRect:(CGRect)rect
{
int heightYouWant = 100;
UIImage *image = [UIImage imageNamed:#"title_bar_bg.png"];
[image drawInRect:CGRectMake(0, 0, self.frame.size.width, heightYouWant)];
self.tintColor = [UIColor colorWithRed:1/255.0 green:62/255.0 blue:130/255.0 alpha:1];
}
Add this method to your subclass of UINavigationBar:
- (void)layoutSubviews {
[super layoutSubviews];
CGRect barFrame = self.frame;
barFrame.size.height = heightYouWant;
self.frame = barFrame;
}

Most idiomatic iOS5 way of customizing the UINavigationBar?

I'm working on customizing the appearance of navigation controllers in my app to look like the following:
As I've discovered after a few hours of SO research, there are a ton of different ways of doing it, some really hackish, some much less so. I'm interested in finding out the Apple-blessed / most elegant way of achieving this that will lead to the least amount of pain down the road as the app grows. Some approaches I've looked into so far:
1) I changed the background / height of the navigation bar by applying an image through [UINavigationBar appearance], seems to have worked fine.
UIImage *navBarImage = [UIImage imageNamed:#"navigation-bar.png"];
[[UINavigationBar appearance] setBackgroundImage:navBarImage
forBarMetrics:UIBarMetricsDefault];
Seems like the most "modern" way of achieving background/height change, although it most likely doesn't survive an orientation change. Any improvements that could be made here?
2) I replaced the default back button with the following in the viewDidLoad of the pushed view
// Set the custom back button
UIImage *buttonImage = [UIImage imageNamed:#"back.png"];
//create the button and assign the image
UIButton *button = [UIButton buttonWithType:UIButtonTypeCustom];
[button setImage:buttonImage forState:UIControlStateNormal];
//set the frame of the button to the size of the image (see note below)
button.frame = CGRectMake(0, 0, buttonImage.size.width, buttonImage.size.height);
[button addTarget:self action:#selector(back) forControlEvents:UIControlEventTouchUpInside];
// offset the back button
button.contentEdgeInsets = UIEdgeInsetsMake(10, 5, -10, -5);
//create a UIBarButtonItem with the button as a custom view
UIBarButtonItem *customBarItem = [[UIBarButtonItem alloc] initWithCustomView:button];
self.navigationItem.leftBarButtonItem = customBarItem;
I'm not very pleased with this solution because it leaves customization of the bar to the controller on top of the navigation stack. From the Apple docs it would seem like they'd prefer you to subclass the UINavigationBar altogether and replace it once and for all in the navigation controller:
You can also specify a custom UINavigationBar subclass by using the initWithNavigationBarClass:toolbarClass: method to initialize the navigation controller.
Would that be the advised route? I was NOT able to replace the default Back button of the UINavigationBar through [UIBarButtonItem appearance] as it still attempts to display text in the button, and when you remove the text, the button isn't displayed at all. Suggestions?
3) The page title should be replaceable with another view through navigationItem.titleView. Anything better out there?
Thanks!
1) You should set two images, for two UIBarMetrics (UIBarMetricsDefault and a separate image for UIBarMetricsLandscapePhone). Thus
UIImage *navBarImage = [UIImage imageNamed:#"navigation-bar.png"];
UIImage *navBarImage_Landscape = [UIImage imageNamed:#"navigation-bar-landscape.png"];
[[UINavigationBar appearance] setBackgroundImage:navBarImage
forBarMetrics:UIBarMetricsDefault];
[[UINavigationBar appearance] setBackgroundImage:navBarImage_Landscape
forBarMetrics:UIBarMetricsLandscapePhone];
2) You could either subclass UINavigationBar (as you've also mentioned and that would be the default Apple way). Or if it's just the button, maybe you could hack its behaviour by passing in " " (empty text)
3) Not sure what you meant. You could setTitle of the navigation bar and it would show whatever title you want. Or you should be able to plug in another view for titleView
Note that setBackgroundImage is iOS 5.0 and later.

UINavigationBar Custom Title View

I am using iOS 5 UINavigationBar's UIAppearance protocol in order to customise all my navigation bars.
Here is my customisation function:
- (void)customizeApperance
{
[[UINavigationBar appearance] setTintColor:[UIColor clearColor]];
[[UINavigationBar appearance] setAlpha:0.7];
UIImageView *titleView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:#"title.png"]];
[[UINavigationBar appearance] setTitleView:titleView];
}
I have two problems:
The first is that the colour not appearing as clearColor but black. Any suggestions?
The title view is not appearing at all. Ray Wenderlich shows how to do that by adding a: [[rootViewController navigationItem] setTitleView: [[UIImageView alloc] initWithImage:[UIImage imageNamed:#"miniLogo.png"]]] in applicationDidFinishLaunching. But the problem with this is that the title view would only be added in the root view controller. I am using a UINavigationController and when I tired to replace the rootViewController with navigationController (the name of my navigation controller in AppDelegate), I cannot see the title view at all. How can I fix that? Why isn't it working in customizeApperance()? Isn't the whole point of using appearance is to just create a title view once (as I did above the function) and have it global in all navigation bars? How can I achieve that?
[UIColor clearColor] is a fully transparent color (alpha = 0). Setting that as tint color makes the (black) background shine through. Perhaps you want [UIColor whiteColor] ?
titleView is a property of UINavigationItem, and each view controller has it's own navigationItem. Therefore you cannot set a title view globally. But you can set the background image of UINavigationBar with the appearance protocol, perhaps that helps:
[[UINavigationBar appearance] setBackgroundImage:image forBarMetrics:UIBarMetricsDefault];
Have you tried titleView.opaque = NO;? If that's set to YES (i.e. by default, since you're using initWithImage:), the drawing system will assume your view fills its entire bounds, and won't bother drawing anything that overlaps its frame.
setTitleView: is a method on NavigationItem. But you are calling it on navigation bar

Adding image to iPhone navigation bar

I want to replace the current nav bar with a custom image. How my code is structured is that a tab bar controller controls a bunch of navigation controllers which contain views (tab bar controller -> nav controller -> view). I tried using this code in my app delegate
#implementation UINavigationBar (UINavigationBarCategory)
- (void)drawRect:(CGRect)rect {
UIColor *color = [UIColor blackColor];
UIImage *img = [UIImage imageNamed: #"nav.png"];
[img drawInRect:CGRectMake(0, 0, self.frame.size.width, self.frame.size.height)];
self.tintColor = color;
}
#end
But it did not work. Any ideas why? Should I have placed it somewhere else? Thanks!
if you are using iOS 5, you can use setBackgroundImage: like this where ever you initialized the navigation controller (aNavigationController in this example):
[aNavigationController.navigationBar setBackgroundImage:[UIImage imageNamed:#"nav.png"] forBarMetrics:UIBarMetricsDefault];
I would not use a category. I would subclass UINavigationBar instead. See this: https://stackoverflow.com/a/6959354/472344
If you are targeting iOS 5 or up, use #BJH's solution instead.