Packaging UINavigationBar image resources for iOS6 / iO7 - ios

I currently develop a sample app that I deliver white-branded to several entities based on their own visual entities.
Since iOS7 and the merge of the UIStatusBar with the UINavigationBar, I have to manage images in a lot of size : #2x for retina, -64h for iOS7 (64px height) and classical one.
I want to support both iOS 5, 6 & 7.
It is quite painful each time I want to deliver for specific entity to photoshop and resize 7 (even 8, here is missing the #2x for iPad) images.
At least for the Icon image it is quite easy as it remains a square whatever the targeted OS or device.
Is their a more productive to package it with fewer image resources ?
I am currently using the following code to set up my navbar image in all the app :
if ([[[UIDevice currentDevice] systemVersion] floatValue] >= 7.0)
[[UINavigationBar appearance] setBackgroundImage:[UIImage imageNamed:#"navbar-64h.png"] forBarMetrics:UIBarMetricsDefault];
else
[[UINavigationBar appearance] setBackgroundImage:[UIImage imageNamed:#"navbar.png"] forBarMetrics:UIBarMetricsDefault];

You can provide just two images (regular and retina), using -[UIImage resizableImageWithCapInsets:], or the Xcode 5 image slicer.
In code
For example:
UIEdgeInsets insets = UIEdgeInsetsMake(1, 1, 1, 1); // represents a 1 point (2 pixel retina) border of your background color around your logo.
UIImage *navBackgroundImage = [UIImage imageNamed:#"background"];
navBackgroundImage = [navBackgroundImage resizableImageWithCapInsets:insets];
[[UINavigationBar appearance] setBackgroundImage:navBackgroundImage forBarMetrics:UIBarMetricsDefault];
The insets should indicate the area of the image that isn't stretchable.
If you want more control over the placement of the logo, make the background color border larger than 1 point, and adjust insets to match.
You can provide different values of insets depending on your device, if necessary.
Xcode 5 Image Slicer
This code is equivalent to Xcode 5's image slicing editor in xcassets files, which is backwards compatible to iOS 5 according to this post.

Related

naviagtionBar height and statusBar height size look like bigger

In the use of the iphone 5, the navigationBar and statusBar normal height, but under the iphone6 or iphone6plus navigationBar and the statusBar height is bigger, not 64, the likelihood is scaling.
The problem is that I want iphone6 or iphone6plus to also become a normal 64, but they don't know how to find this code in the project.
/Users/henry/Desktop/question1.jpg
You need to specify Launch Images for the iPhone 6 / + resolutions, either as individual image files or define a XIB / storyboard file (for iOS 8+). Otherwise your app will run in that zoomed sort of compatibility mode that you're seeing-- apple created that when they introduced the iPhone 6 & 6+ which were of different aspect ratios than any iPhones before them so apps that weren't updated for the new phones didn't look entirely awful when the new phones came out.
see:
https://developer.apple.com/library/ios/documentation/UserExperience/Conceptual/MobileHIG/LaunchImages.html
Try this code. make sure that image "navbg.png" height 64.
[[UIApplication sharedApplication] setStatusBarStyle:UIStatusBarStyleLightContent];
[[UINavigationBar appearance] setShadowImage:[UIImage new]];
[[UINavigationBar appearance] setBackgroundImage:[UIImage imageNamed:#"navbg.png"] forBarMetrics:UIBarMetricsDefault];
[[UINavigationBar appearance] setTranslucent:NO];
[[UINavigationBar appearance] setTintColor:[UIColor whiteColor]];

UINavigationBar appearance different in iOS7 and iOS8

The following code works perfectly on iOS8 but has a strange behavior on iOS7.
[[UINavigationBar appearance] setBackIndicatorImage:[UIImage imageNamed:#"icone retour#2x.png"]];
[[UINavigationBar appearance] setBackIndicatorTransitionMaskImage:[UIImage imageNamed:#"icone retour#2x.png"]];
See images below. Any idea ?
You should not directly reference the #2x or #3x version of your images, but rather just reference the "base" name and let iOS automatically determine the correct variant for the current device:
[UIImage imageNamed:#"icone retour.png"]
Regarding the different behavior in iOS7 vs. iOS8 I can only speculate that iOS8 has changed the behavior in imageNamed: with regard to the scale of the returned UIImage when passing an image with #2x or #3x in the name. But you should usually not do this anyways.

UINavigationBar background - how to cover all sizes, resolutions and devices?

I have the following code that works fine for setting a background image:
[self.navigationController.navigationBar setBackgroundImage:[UIImage imageNamed: #"navbar_bg.png"] forBarMetrics:UIBarMetricsDefault];
My question is, for Xcode6, iOS8/9, iPhone 5, 6, 6+, iPad, etc, how do I make sure I cover all devices, widths and resolutions, to make sure that my background image always fills the navigation bar correctly?
I have seen other questions on SO and various other sites, but all have been 2-4 years old, and so don't mention or cover the latest device widths and resolutions.
I want to use a background image in the navigation bar, but I need to make sure it looks good on all possible devices.
All you have to do is have three versions of your image in your asset catalogue. The first in the size you need the second twice the size and the third three times the size. Xcode will put the right image on the right device.
Alternatively you can just put a vectorial image and at complie time Xcode will generate the three images for you on the fly.
For the navigation bar you need separate images for portrait and landscape. You can write something like this:
UIImage *portraitImage = [UIImage imageNamed:#"test_bar_portrait.png"];
UIImage *landscapeImage = [UIImage imageNamed:#"test_bar_landscape.png"];
[[UINavigationBar appearance] setBackgroundImage:portraitImage forBarMetrics:UIBarMetricsDefault];
[[UINavigationBar appearance] setBackgroundImage:landscapeImage forBarMetrics:UIBarMetricsLandscapePhone];
self.navigationController.navigationBar.autoresizingMask = UIViewAutoresizingFlexibleTopMargin;

How to support different tab bar icon sizes in iOS 7 and iOS 6?

In iOS 7 Apple increased the standard size of tab bar icons. If the tab bar icons are set in a storyboard, how can you support both iOS 6 and iOS 7 interfaces simultaneously? Do you have to make a separate storyboard for iOS 7?
Programmatically adjust the icon if you're in iOS 7?
I'm mostly confused because the documentation doesn't seem to mention anything about differently sized icons for tab bars (https://developer.apple.com/library/ios/documentation/userexperience/conceptual/TransitionGuide/TransitionGuide.pdf page 26)
In fact the icons look almost identical.
But when I run my app in iOS 7 all the icons appear shrunk down.
You can use following method to check the version of current iOS and then customize the button size and appearance of the navigation bar buttons.
if (floor(NSFoundationVersionNumber)<=NSFoundationVersionNumber_iOS_6_1) {
UIImage *navBarImage=[[UIImage imageNamed:#"top-bar-bg-44px.png"] resizableImageWithCapInsets:UIEdgeInsetsMake(0, 0, 0, 0)];
[[UINavigationBar appearance] setBackgroundImage:navBarImage forBarMetrics:UIBarMetricsDefault];
UIImage *barButtonImg=[[UIImage imageNamed:#"back-ios6.png"]
resizableImageWithCapInsets:UIEdgeInsetsMake(0, 13, 0, 5)];
[[UIBarButtonItem appearance] setBackButtonBackgroundImage:barButtonImg forState:UIControlStateNormal barMetrics:UIBarMetricsDefault];
}
else{
}
After some digging, I found the answer over here - Tab bar icons on retina display
"You need to create two separate icons icon.png (30x30) and icon#2x.png (60x60).
iOS will automatically load the right file based on the screen scale."

Custom styling of UINavigationBar not working properly

I am using this code to set custom background image for all UINavigationBars. The problem is that the final image does not appear to be retina size. I researched UINavigationBars are 640x88px. Thats exact dimensions of my UINavigationBar.png however I only see 320x44px on the iPhone Sim(retina) and my iphone 4 which is also retina.
The code that sets the image:
UIImage *background = [UIImage imageNamed:#"UINavigationBar.png"];
[[UINavigationBar appearance] setBackgroundImage:background forBarMetrics:UIBarMetricsDefault];
Here is a screenshot for illustration:
(the difference is there is no bottom dark line as in Photoshop. I can only see half of the image in the iPhone 5 Simulator (Retina))
My question is why this happens and how can I fix it? Thanks.
You need to have two .png files with different size and same name, but with #2x addition in the retina display file.
For example,
File 1 for regular display support:
size- 320x44,
name- UINavigationBar.png
File 2 for retina display support:
size- 640x88,
name- UINavigationBar#2x.png
In your code you always use UINavigationBar.png, the device will automatically know witch file to use, according to the hardware.

Resources