如何在某些视图而非全部视图上更改带有图像的UINavigationBar背景? [英] How to change UINavigationBar background with image on some views but not all?

查看:46
本文介绍了如何在某些视图而非全部视图上更改带有图像的UINavigationBar背景?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想将图像设置为UINavigationController背景,但是我发现大多数解决方案都在导航栏中为应用程序中的所有视图应用背景.您能提供一些可能有用的代码吗?

I would like to set an image as UINavigationController background but most solutions I found apply background in navigation bar for all views in the app. Can you give some code that may help ?

感谢,

Stephane

推荐答案

在我的一个项目中,这是一种快速而肮脏的方式(我不需要支持横向).我使用方法混淆将其实现为UINavigationBar的类别.在iOS 4和5上运行(我没有在iOS 3上尝试过).

Here's a quick and dirty way that I use in one of my projects (I have no need to support landscape orientation). I implemented it with a category to UINavigationBar with method swizzling. Works on iOS 4 and 5 (I didn’t try it on 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

然后,如果要在一个UINavigationController中更改图像,则在viewWillAppear中设置背景图像,并在viewWillDisappear中将其还原.

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.

这篇关于如何在某些视图而非全部视图上更改带有图像的UINavigationBar背景?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆