UINavigationBar backgroundImageForBarMetrics
- (UIImage *)backgroundImageForBarMetrics:(UIBarMetrics)barMetrics
Parameters
barMetrics
A bar metrics constant.
Return Value of [UINavigationBar backgroundImageForBarMetrics]
The background image for barMetrics.
UINavigationBar backgroundImageForBarMetrics example.
UINavigationBar *appearanceProxBar = [UINavigationBar appearance];
UIImage *defaultImage = [appearanceProxBar backgroundImageForBarMetrics:UIBarMetricsDefault];
[appearanceProxBar setBackgroundImage:navBarTexture forBarMetrics:UIBarMetricsDefault];
[[UINavigationBar appearanceWhenContainedIn:[UIPopoverController class], nil] setBackgroundImage:defaultImage forBarMetrics:UIBarMetricsDefault];
UIImage *defaultImage = [appearanceProxBar backgroundImageForBarMetrics:UIBarMetricsDefault];
[appearanceProxBar setBackgroundImage:navBarTexture forBarMetrics:UIBarMetricsDefault];
[[UINavigationBar appearanceWhenContainedIn:[UIPopoverController class], nil] setBackgroundImage:defaultImage forBarMetrics:UIBarMetricsDefault];
Example of [UINavigationBar backgroundImageForBarMetrics].
UINavigationBar+SYCustomBackground.h
#import <UIKit/UIKit.h>
@interface UINavigationBar (SYCustomBackground)
@property (nonatomic,retain) UIImage *sy_customBackgroundImage;
@end
UINavigationBar+SYCustomBackground.m
#import "UINavigationBar+SYCustomBackground.h"
#import <objc/runtime.h>
@implementation UINavigationBar (SYCustomBackground)
static char BACKGROUND_IMAGE_KEY;
static BOOL drawRectsSwizzled = NO;
// Swizzles drawRect: and sy_drawRect:
- (void)swizzleDrawRectIfNecessary
{
if (!drawRectsSwizzled) {
Method origMethod = class_getInstanceMethod([self class], @selector(drawRect:));
Method myMethod = class_getInstanceMethod([self class], @selector(sy_drawRect:));
method_exchangeImplementations(origMethod, myMethod);
drawRectsSwizzled = YES;
}
}
- (void)setSy_customBackgroundImage:(UIImage *)image
{
// iOS 5
if ([self respondsToSelector:@selector(setBackgroundImage:forBarMetrics:)]) {
[self setBackgroundImage:image forBarMetrics:UIBarMetricsDefault];
}
// iOS < 5
else {
[self swizzleDrawRectIfNecessary];
objc_setAssociatedObject(self, &BACKGROUND_IMAGE_KEY, image, OBJC_ASSOCIATION_RETAIN);
}
}
- (UIImage *)sy_customBackgroundImage
{
// iOS 5
if ([self respondsToSelector:@selector(setBackgroundImage:forBarMetrics:)]) {
return [self backgroundImageForBarMetrics:UIBarMetricsDefault];
}
// iOS < 5
else {
[self swizzleDrawRectIfNecessary];
return objc_getAssociatedObject(self, &BACKGROUND_IMAGE_KEY);
}
}
- (void)sy_drawRect:(CGRect)rect
{
UIImage *backgroundImage = self.sy_customBackgroundImage;
if (backgroundImage) {
[backgroundImage drawInRect:rect];
}
else {
// No custom image, calling original drawRect:
// Note: it’s swizzled, so we must call sy_drawRect:
[self sy_drawRect:rect];
}
}
@end
Then you set your background images in viewWillAppear and restore them in viewWillDisappear if you want to change images in one UINavigationController.
It’s not perfect, I would add some crossfade transition, add push/pop for backgrounds, but I have no time yet, so feel free to improve it.
#import <UIKit/UIKit.h>
@interface UINavigationBar (SYCustomBackground)
@property (nonatomic,retain) UIImage *sy_customBackgroundImage;
@end
UINavigationBar+SYCustomBackground.m
#import "UINavigationBar+SYCustomBackground.h"
#import <objc/runtime.h>
@implementation UINavigationBar (SYCustomBackground)
static char BACKGROUND_IMAGE_KEY;
static BOOL drawRectsSwizzled = NO;
// Swizzles drawRect: and sy_drawRect:
- (void)swizzleDrawRectIfNecessary
{
if (!drawRectsSwizzled) {
Method origMethod = class_getInstanceMethod([self class], @selector(drawRect:));
Method myMethod = class_getInstanceMethod([self class], @selector(sy_drawRect:));
method_exchangeImplementations(origMethod, myMethod);
drawRectsSwizzled = YES;
}
}
- (void)setSy_customBackgroundImage:(UIImage *)image
{
// iOS 5
if ([self respondsToSelector:@selector(setBackgroundImage:forBarMetrics:)]) {
[self setBackgroundImage:image forBarMetrics:UIBarMetricsDefault];
}
// iOS < 5
else {
[self swizzleDrawRectIfNecessary];
objc_setAssociatedObject(self, &BACKGROUND_IMAGE_KEY, image, OBJC_ASSOCIATION_RETAIN);
}
}
- (UIImage *)sy_customBackgroundImage
{
// iOS 5
if ([self respondsToSelector:@selector(setBackgroundImage:forBarMetrics:)]) {
return [self backgroundImageForBarMetrics:UIBarMetricsDefault];
}
// iOS < 5
else {
[self swizzleDrawRectIfNecessary];
return objc_getAssociatedObject(self, &BACKGROUND_IMAGE_KEY);
}
}
- (void)sy_drawRect:(CGRect)rect
{
UIImage *backgroundImage = self.sy_customBackgroundImage;
if (backgroundImage) {
[backgroundImage drawInRect:rect];
}
else {
// No custom image, calling original drawRect:
// Note: it’s swizzled, so we must call sy_drawRect:
[self sy_drawRect:rect];
}
}
@end
Then you set your background images in viewWillAppear and restore them in viewWillDisappear if you want to change images in one UINavigationController.
It’s not perfect, I would add some crossfade transition, add push/pop for backgrounds, but I have no time yet, so feel free to improve it.