UINavigationBar arka planını bazı görünümlerde görüntüyle nasıl değiştirirsiniz?

Bir görüntüyü UINavigationController arka planı olarak ayarlamak istiyorum, ancak bulduğum çoğu çözüm, gezinme çubuğundaki arka planda uygulamadaki tüm görünümler için geçerli. Yardımcı olabilecek bir kod verebilir misiniz?

Yardım için teşekkürler,

Stephane

1

5 cevap

Bu, gezinti denetleyicisi için arka plan görüntüsünü ayarlamanın doğru yoludur. Bu iOS 5'te mevcuttur.

[navBar setBackgroundImage:[UIImage imageNamed: @"image.png"] forBarMetrics:UIBarMetricsDefault];
6
katma
Sadece bir tek uiview arka planını değiştirmek istiyorsanız, belki bu işe yaramaz. Nav denetleyicisinin tüm uiview için çalışır.
katma yazar giuseppe, kaynak
Evet, bu çoğu halkın sorununa bir çözüm olabilir, ancak bu işlev arka planı "ayarlayamadı".
katma yazar Pork 'n' Bunny, kaynak

İşte projelerimden birinde kullanmamın hızlı ve kirli bir yolu (peyzaj yönünü desteklemeye ihtiyacım yok). Metot swizzling ile UINavigationBar için bir kategori ile uyguladım. İOS 4 ve 5'te çalışır (iOS 3'te denemedim).

UINavigationBar + SYCustomBackground.h

#import 

@interface UINavigationBar (SYCustomBackground)
@property (nonatomic,retain) UIImage *sy_customBackgroundImage;
@end

UINavigationBar + SYCustomBackground.m

#import "UINavigationBar+SYCustomBackground.h"
#import 

@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

Ardından, arka plan resimlerinizi viewWillAppear olarak ayarlayın ve görüntüleri bir UINavigationController içinde değiştirmek istiyorsanız, onları viewWillDisappear konumuna geri yükleyin.

Mükemmel değil, biraz sınır ötesi geçiş ekleyeceğim, arka planlar için push/pop ekleyeceğim, ancak henüz vaktim yok, bu yüzden onu geliştirmek için çekinmeyin.

3
katma

Açıkçası, bir görüntünün gezinme çubuğunun arka planı olarak nasıl ayarlanacağını zaten biliyorsunuz.

Farklı görünüm denetleyicileri arasında ayrım yapmanız gerekirse, farklı davranması gereken bir görünüm denetleyicinin çubuğunu viewWillAppear ve viewWillDisappear öğelerinde değiştirmeniz gerekir. Kaptın bu işi.

2
katma

merhaba Stephane Kouakou,

bu işe yarıyor

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

özellikle View`s willAppear yöntemi

0
katma
BackgroundView değil demek istedim :)
katma yazar Steve, kaynak
titleView arka planlar için değil.
katma yazar Stanislav Yaglo, kaynak

Bunun, iOS5 için ilk gerçek cevap olduğuna inanıyorum, asıl sorun, bir kez yaptıktan sonra arka plan görüntüsünün "kaldırılması". Sadece mevcut olanı koru.

@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
katma