IOS 7 navigation bar background image issue
I am using an image as the background image of the navigation bar. I used the following code to set the image:
[[UINavigationBar appearance] setBackgroundImage:[UIImage imageNamed:@"nav_logo_ios7.png"] forBarMetrics:UIBarMetricsDefault];
For iOS7 "nav_logo_ios7.png" the image size is 768x64, and for iOS6 and below I used a 768x44 image.
This works well for everyone UIViewControllers
.
In the same project I am using UIActivityViewController
. In iOS7 mail view, the view looks like this:
How can I handle this?
Thanks in advance.
source to share
The problem you are having is that when the UIViewController is presented modally, the status bar is not included in the height of the UINavigationBar.
This means the 64-bit image is wrong.
First of all, the official and best way to check which version of iOS device is running is to do something like this:
if (NSFoundationVersionNumber > NSFoundationVersionNumber_iOS_6_1)
{
//handle iOS 7 Stuff
}
else
{
//handle older iOS versions
}
Check out the title for more information NSObjCRuntime.h
.
UINavigationBar background images should not be fixed size images, but instead should be stretchable images such as a repeatable pattern, so it might be an idea to rethink future designs ... However, if you want to continue working with a regular fixed size image, then I have a suggestion for you ...
UINavigationController allows you to initialize an instance with custom UINavigationBar and UIToolbar classes using initWithNavigationBarClass:toolbarClass:
... This means you can initialize any views that you do not present in models with another UINavigationBar subclass so that views that are modally exposed.
This means that you can specify different background images depending on whether your navigation controller is presented modally or not, for example:
UIImage *backgroundImage44pts = [UIImage imageNamed:@" ... "];
UIImage *backgroundImage64pts = [UIImage imageNamed:@" ... "];
if (NSFoundationVersionNumber > NSFoundationVersionNumber_iOS_6_1)
{
//handle iOS 7 Stuff
[[UINavigationBar appearance] setBackgroundImage:backgroundImage44pts forBarMetrics:UIBarMetricsDefault];
[[UINavigationBarSubclass appearance] setBackgroundImage:backgroundImage64pts forBarMetrics:UIBarMetricsDefault];
}
else
{
//handle older iOS versions
[[UINavigationBar appearance] setBackgroundImage:backgroundImage44pts forBarMetrics:UIBarMetricsDefault];
}
It is important to note that MFMailComposeViewController is not a real view controller, so trying to initialize it with custom navbar subclasses might not work. This is why I used a custom navbar subclass for all modeless nav controllers and not the other way around.
Another note: if your app is generic then modal views don't exist (unless you have any custom settings) and you don't have to worry about that.
As I said earlier ... UINavigationBars are not really meant for fixed background images (which is why they are so hard to achieve), so if you think this job is too complicated it might be a good idea to rethink your design.
One last thing I promise ... One of the major design changes in iOS 7 is that your content is in the navigation bar, which is below the status bar. Adding an image to prevent this and replacing it with a solid white background seems rather odd for an iOS 7 app.
source to share
//In `AppDelegate.m`
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
if([[[UIDevice currentDevice] systemVersion] floatValue] < 7.0)
{
[[UINavigationBar appearance] setBackgroundImage:[UIImage imageNamed:@"nav_bg.png"] forBarMetrics:UIBarMetricsDefault];
[[UINavigationBar appearance] setTitleTextAttributes:
@{
UITextAttributeTextColor: [UIColor whiteColor],UITextAttributeTextShadowColor: [UIColor clearColor],UITextAttributeTextShadowOffset: [NSValue valueWithUIOffset:UIOffsetMake(0.0f, 1.0f)],UITextAttributeFont: [UIFont fontWithName:@"ArialMT" size:18.0f]
}];
CGFloat verticalOffset = -4;
[[UINavigationBar appearance] setTitleVerticalPositionAdjustment:verticalOffset forBarMetrics:UIBarMetricsDefault];
}
else
{
[[UINavigationBar appearance] setBarTintColor:[UIColor whiteColor]];
// Uncomment to change the color of back button
[[UINavigationBar appearance] setTintColor:[UIColor whiteColor]];
// Uncomment to assign a custom backgroung image
[[UINavigationBar appearance] setBackgroundImage:[UIImage imageNamed:@"nav_bg_ios7.png"] forBarMetrics:UIBarMetricsDefault];
// Uncomment to change the back indicator image
[[UINavigationBar appearance] setBackIndicatorImage:[UIImage imageNamed:@""]];
[[UINavigationBar appearance] setBackIndicatorTransitionMaskImage:[UIImage imageNamed:@""]];
// Uncomment to change the font style of the title
NSShadow *shadow = [[NSShadow alloc] init];
shadow.shadowColor = [UIColor colorWithRed:0.0 green:0.0 blue:0.0 alpha:0.8];
shadow.shadowOffset = CGSizeMake(0, 1);
[[UINavigationBar appearance] setTitleTextAttributes: [NSDictionary dictionaryWithObjectsAndKeys:[UIColor colorWithRed:245.0/255.0 green:245.0/255.0 blue:245.0/255.0 alpha:1.0], NSForegroundColorAttributeName,shadow, NSShadowAttributeName,[UIFont fontWithName:@"ArialMT" size:18.0], NSFontAttributeName, nil]];
CGFloat verticalOffset = -4;
[[UINavigationBar appearance] setTitleVerticalPositionAdjustment:verticalOffset forBarMetrics:UIBarMetricsDefault];
}
self.window.rootViewController = self.navigationController;
[self.window makeKeyAndVisible];
return YES;
}
source to share