Как изменить фон UINavigationBar с изображением на некоторых видах, но не на всех? - PullRequest
1 голос
/ 28 октября 2011

Я хотел бы установить изображение в качестве фона UINavigationController, но большинство найденных решений применяют фон на панели навигации для всех представлений в приложении. Можете ли вы дать код, который может помочь?

Спасибо за помощь,

Stephane

Ответы [ 5 ]

6 голосов
/ 13 января 2012

Это правильный способ установить фоновое изображение для контроллера навигации. Это доступно в ios 5.

[navBar setBackgroundImage:[UIImage imageNamed: @"image.png"] forBarMetrics:UIBarMetricsDefault];
3 голосов
/ 28 октября 2011

Вот быстрый и грязный способ, которым я пользуюсь в одном из своих проектов (мне не нужно поддерживать альбомную ориентацию).Я реализовал это с категорией 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.

Этоне идеально, я бы добавил переход с плавным переходом, добавил push / pop для фона, но у меня пока нет времени, так что не стесняйтесь его улучшать.

2 голосов
/ 28 октября 2011

Очевидно, вы уже знаете, как установить изображение в качестве фона панели навигации.

Если вам необходимо различать различные контроллеры вида, вам нужно изменить панель в viewWillAppear и * 1004.* одного контроллера представления, который должен вести себя по-другому.Вы поняли.

0 голосов
/ 14 августа 2013

Я полагаю, что это первый фактический ответ на этот вопрос для iOS5, основной проблемой является «удаление» фонового изображения, как только вы закончите.Ну, просто сохраните существующий.

@implementation MyViewController {
    UIImage *_defaultImage;
}

- (void)viewWillAppear:(BOOL)animated {   
    _defaultImage = [self.navigationController.navigationBar backgroundImageForBarMetrics:UIBarMetricsDefault];
    [self.navigationController.navigationBar setBackgroundImage:[UIImage imageNamed:@"bar.png"] forBarMetrics:UIBarMetricsDefault];
}

- (void)viewWillDisappear:(BOOL)animated {
    [self.navigationController.navigationBar setBackgroundImage:_defaultImage forBarMetrics:UIBarMetricsDefault];
}
0 голосов
/ 28 октября 2011

привет Стефан Куаку,

попробуй это работает ...

 UIImageView *bgNavigation= [[UIImageView alloc] initWithImage:[UIImage imageNamed: @"bgNav.png"]];    
    self.navigationItem.titleView = bgNavigation;    
    [bgNavigation release];

в частности, метод willAppear от ViewView

...