Вот быстрый и грязный способ, который я использую в одном из своих проектов (у меня нет необходимости поддерживать альбомную ориентацию). Я реализовал его с категорией до UINavigationBar
методом swizzling. Работает на iOS 4 и 5 (на iOS 3 не пробовал).
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
Затем вы устанавливаете свои фоновые изображения в viewWillAppear
и восстанавливаете их в viewWillDisappear
, если хотите изменить изображения в одном UINavigationController
.
Это не идеально, я бы добавил кроссфейд-переход, добавил пуш/поп для фона, но у меня пока нет времени, так что не стесняйтесь улучшать.
person
Stanislav Yaglo
schedule
28.10.2011