Ipad NavigationBar Landscape Issue - ipad

is there a way to use a different images for the ipad landscape/portrait mode? My navigationbar contains a logo in the middle and while it works great on the iphone with different images, I can't use different images for the iPad so the logo isn't centered when you turn the device.
Alternatively, I can use a plain background image and maybe replace the navigation bar title with an image or center a button but I also couldn't manage to do that either. (I don't have a UINavigationController subclass).
here is my code that is doing the trick so far inside the app delegate:
if ([UINavigationBar respondsToSelector:#selector(appearance)]) {
// Create resizable images for iphone
UIImage *navbarImage44 = [[UIImage imageNamed:#"nav_bar"]
resizableImageWithCapInsets:UIEdgeInsetsMake(0, 0, 0, 0)];
UIImage *navbarImage32 = [[UIImage imageNamed:#"nav_bar_landscape"]
resizableImageWithCapInsets:UIEdgeInsetsMake(0, 0, 0, 0)];
// Overide for iPad
// In theory navbar_bg_landscape~iPad should work
if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad) {
//use iPad specific image extending last pixel for landscape mode
[[UINavigationBar appearance] setBackgroundImage:[[UIImage imageNamed:#"nav_bar_ipad" ]
resizableImageWithCapInsets:UIEdgeInsetsMake(0, 0, 0, 0)]
forBarMetrics:UIBarMetricsDefault];
}else {
// Set the background image for *all* UINavigationBars
[[UINavigationBar appearance] setBackgroundImage:navbarImage44
forBarMetrics:UIBarMetricsDefault];
// Never called on iPad, used for landscape on iPhone
[[UINavigationBar appearance] setBackgroundImage:navbarImage32
forBarMetrics:UIBarMetricsLandscapePhone];
}
}

I didn't get any response on this so I found a work around which is to resize the image on landscape. I'm ok with that for now. I'm resizing my portrait background image - here is my code for iPad
// Create resizable images
UIImage *ipadTabBarBG = [[UIImage imageNamed:#"nav_bar_ipad.png"]
resizableImageWithCapInsets:UIEdgeInsetsMake(0, -260, 0, 0)];
// Set the background image for *all* UINavigationBars
[[UINavigationBar appearance] setBackgroundImage:ipadTabBarBG
forBarMetrics:UIBarMetricsDefault];

Related

Center UIImage in UINavigationController

I'm trying to center a background UIImage in a UINavigationController that's instantiated in code:
UINavigationController *navController = [[UINavigationController alloc] initWithRootViewController:mainMenuViewController];
self.window.rootViewController = navController;
UIImage *navBackgroundImage = [UIImage imageNamed:#"fancy_header_logo"];
navBackgroundImage = [navBackgroundImage imageWithRenderingMode:UIImageRenderingModeAlwaysOriginal];
[[UINavigationBar appearance] setBackgroundImage:navBackgroundImage forBarMetrics:UIBarMetricsDefault];
[[UINavigationBar appearance] setBarStyle:UIBarStyleBlack];
[navController.navigationBar setContentMode:UIViewContentModeCenter];
navController.navigationBar.autoresizingMask = UIViewAutoresizingFlexibleTopMargin;
The image displays correctly in portrait on all devices except for the iPhone 6. The image is stored in Images.xcassets in 1x, 2x, Retina 4 2x, 3x, and iPad 2x sizes.
Any pointers or suggestions would be greatly appreciated. Many thanks in advance.
UPDATE:
I've made some progress. Taking a hint from this answer I made some changes:
UINavigationController *navController = [[UINavigationController alloc] initWithRootViewController:mainMenuViewController];
self.window.rootViewController = navController;
UIImage *navBackgroundImage = [[UIImage imageNamed:#"fancy_header_logo"] resizableImageWithCapInsets:UIEdgeInsetsMake(0, -260, 0, 0)];
[[UINavigationBar appearance] setBackgroundImage:navBackgroundImage forBarMetrics:UIBarMetricsDefault];
[[UINavigationBar appearance] setBarStyle:UIBarStyleBlack];
This now works in all cases except iPhone 6 (not plus) in portrait (the app does not rotate on iPhones.) Now the image is scaled larger and instead of being left justified, it is now scaled larger and is too far to the right.
For the record, the image is being used when stepping through the code running in the iPhone simulator is 640x128 at 144 ppi.
UPDATE 2:
It appears that the iPhone 6 is using the image listed as 2x (in the .xcassets file) This is the same file as used by the iPhone 4 (in the simulator.) I have tried massaging the png file so that it displays right on the iPhone 6, but makes it display incorrectly on the iPhone 4.
Im not sure if this is the correct answer or not but I discovered that it doesn't seem to natively show as an iPhone 6 and 6 plus application unless your app has a launch image for the bigger iPhones.
Try just adding a launch image for these devices :)
Check this:
UIImage *image = [UIImage imageNamed: #"logo"];
UIImageView *imageView = [[UIImageView alloc] initWithImage: image];
self.navigationItem.titleView = imageView;

Contdition load of UI elements

I am trying to customize UI appearance of my app. I used following code, whcih works fine on non iPhone5 and successors (and non retina display), It appears great on simulator.
but on my iPhone5 its not loading the images.
-(void)customizeAppearance
{
UIImage* blueBG = [UIImage imageNamed:#"menubar.png"];
[[UINavigationBar appearance] setBackgroundImage:blueBG forBarMetrics:UIBarMetricsDefault];
UIImage* blueBack = [UIImage imageNamed:#"back.png"];
[[UIBarButtonItem appearance] setBackButtonBackgroundImage:blueBack forState:UIControlStateNormal barMetrics:UIBarMetricsDefault];
UIImage* blueTabBG = [UIImage imageNamed:#"tabbar-active.png"];
[[UITabBar appearance] setBackgroundImage:blueTabBG];
How can I make this conditional load of resource like
if(___IPHONE5ORLATER)
load retina images
else
load non retina images
You don't have to use this type of condition for load retina images,
Put two images
menubar.png (non retina) (e.g 30 X 30 px)
menubar#2x.png (retina image) (e.g 60 X 60 px)
Now you simple use
UIImage* blueBG = [UIImage imageNamed:#"menubar"];
iOS will automatically load retina image if device is retina.

NavigationBar Image on iOS 6.1 too large

In my app, I have custom navigation bars using images. I load them up in viewWillAppear like so:
-(void)viewWillAppear:(BOOL)animated {
UIImage *gradientImage46 = [[UIImage imageNamed:#"navbar2.png"]resizableImageWithCapInsets:UIEdgeInsetsMake(0, 0, 0, 0)];
[self.navigationController.navigationBar setBackgroundImage:gradientImage46 forBarMetrics:UIBarMetricsDefault];
[super viewWillAppear:animated];
}
On iOS 7, this is fine, but I just noticed on 6.1, the bar is much too large and looks like this:
Thoughts as to what's happening?

How do I an image at a specific location in a navigation bar?

Im customizing my navbars so they all have a logo in them. I want to add the logo right around here:
I know navbars have a background image property but that would stretch it to the whole navbar. I just want it there! :)
So far Ive tried this:
UIImage *gradientImage44 = [[UIImage imageNamed:#"NavBar25High"] resizableImageWithCapInsets:UIEdgeInsetsMake(0, 0, 0, 0)];
UIImage *gradientImage32 = [[UIImage imageNamed:#"NavBar25High"] resizableImageWithCapInsets:UIEdgeInsetsMake(0, 0, 0, 0)];
// Set the background image for *all* UINavigationBars
[[UINavigationBar appearance] setBackgroundImage:gradientImage44 forBarMetrics:UIBarMetricsDefault];
[[UINavigationBar appearance] setBackgroundImage:gradientImage32 forBarMetrics:UIBarMetricsLandscapePhone];
But thats for gradients because as I mentioned, it uses the image as a background image :(
I would allocate an ImageView using CGRectMake to the specific location you want it and add that image view to the view of the UINavigationController.
Like this:
Declare the image
UIImage *myImage =[UIImage imageNamed:#"header.png"];
Allocate the image view
myImageView_tools = [[UIImageView alloc] initWithFrame:CGRectMake(97.5, 20, 125, 45)];
Set the image as the image of the imageview
myImageView_tools.image = myImage;
Add this to your navbar.
[nameofyournavbar.view addSubview:myImageView_tools];
In my code I happened to add it to the RootViewController instead of the NavigationBar but I would imagine it would work just the same.
How about adding the image as the custom view of a UIBarButtonItem. Maybe using a UIBarButtonSystemItemFixedSpace item with a specified width.

setBackButtonBackgroundImage with weird appearance

using this in AppDelegate.m for my custom NavBar:
UIImage *NavigationPortraitBackground = [[UIImage imageNamed:#"gradient_main"] resizableImageWithCapInsets:UIEdgeInsetsMake(0, 0, 0, 0)];
[[UINavigationBar appearance] setBackgroundImage:NavigationPortraitBackground forBarMetrics:UIBarMetricsDefault];
UIImage *barBackBtnImg = [[UIImage imageNamed:#"btn_nav_default.png"] resizableImageWithCapInsets:UIEdgeInsetsMake(0, 0, 0, 0)];
[[UIBarButtonItem appearance] setBackButtonBackgroundImage:barBackBtnImg forState:UIControlStateNormal barMetrics:UIBarMetricsDefault];
results in:
As you can see the button seems to be repeated. Button dimensions are 61x30. And the text is not centered.
If the text is shorter (e.g. Menu) the button image is cut off and if text is longer, then button is repeating.
Similar problem with buttons that have a smaller icon (30x30). The button shows fine but I can click in the button outside of the image :(
The root of your problem is that you are providing a resizeable image without UIEdgeInsets and without specifying the resizing style. The text on your UIBarButtonItem is actually centered! If you measure the distance on both sides of the text, you'll realize that it's the same.
If you look at the image you provide for the UIBarButtonItem:
[[UIImage imageNamed:#"btn_nav_default.png"] resizableImageWithCapInsets:UIEdgeInsetsMake(0, 0, 0, 0)];
You're telling iOS that #"btn_nav_default.png" is a resizeable image and that it should tile. It's basically taking copies of your image and placing them side by side until the full width is covered. If you look at UIImage's Documentation you'll see that the default behaviour for resizableImageWithCapInsets is to tile. You will want to call resizableImageWithCapInsets:resizingMode: and pass in UIImageResizingModeStretch for your resizing mode.
That being said, that won't be enough. What you'll see after that is that the entire image is stretched, completely destroying your nice rounded corners. You need to provide UIEdgeInsets that tell UIImage that "you cannot stretch this section". In this case, providing UIEdgeInsets of UIEdgeInsetsMake(0.0f, 10.0f, 0.0f, 10.0f) (or something similar) will work.
If you're not interested in the long explanation, copy paste this code (no guarantees that this compiles though...):
[[UIImage imageNamed:#"btn_nav_default.png"] resizableImageWithCapInsets:UIEdgeInsetsMake(0.0f, 10.0f, 0.0f, 10.0f) resizingMode:UIImageResizingModeStretch];
You can try to play with
[[UIBarButtonItem appearance] setBackButtonBackgroundVerticalPositionAdjustment:5 forBarMetrics:UIBarMetricsDefault];
in ios 5 after you put the insets

Resources