Как изменить фон панели навигации с изображением на некоторых представлениях, но не на всех?

#iphone #ios #ios4 #uinavigationcontroller #uinavigationbar

#iPhone #iOS #ios4 #uinavigationcontroller #панель навигации

Вопрос:

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

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

Стефан

Ответ №1:

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

 [navBar setBackgroundImage:[UIImage imageNamed: @"image.png"] forBarMetrics:UIBarMetricsDefault];
 

Комментарии:

1. Возможно, это не сработает, если вы хотите изменить только один фон uiview. Это работает для всех uiview навигационного контроллера.

2. Да, это может быть решением проблем большинства пользователей, но эта функция не может «сбросить» фон.

Ответ №2:

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

Ответ №3:

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

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

Ответ №4:

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

попробуйте это, это работает…

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

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

Комментарии:

1. titleView не для фона.

2. Я имел в виду фон, а не titleView 🙂

Ответ №5:

Я считаю, что это первый реальный ответ на этот вопрос для 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];
}