简体   繁体   English

如何在不使用drawRect类别的情况下将图像设置为导航栏背景?

[英]How to set an image as Navigation Bar Background without using a drawRect category?

I would like to set an image background to the navigation bar on my iphone app. 我想在iPhone应用程序的导航栏上设置图像背景。 Most solutions suggest using drawRect in a category like: 大多数解决方案建议在以下类别中使用drawRect:

@implementation UINavigationBar (CustomImage)
- (void)drawRect:(CGRect)rect {
    UIImage *image = [UIImage imageNamed: @"NavigationBar.png"];
    [image drawInRect:CGRectMake(0, 0, self.frame.size.width, self.frame.size.height)];
}
@end

However, Apple does not recommend this . 但是, Apple不建议这样做 Any other suggestion? 还有其他建议吗?

Thx for helping, 感谢您的帮助,

Stephane 斯蒂芬

Apple strongly advise us to use subclasses rather than categories (WWDC 2011, Session 123). Apple强烈建议我们使用子类而不是类别(WWDC 2011,第123节)。

Create a subclass which implements the drawRect: method and set the class of your navigation bar to your custom class: 创建一个实现drawRect:方法的子类,并将导航栏的类设置为自定义类:

  • if you're working in Interface Builder, change the class in the inspector 如果您使用的是Interface Builder,请在检查器中更改类
  • if you create a stand-alone navigation bar (without nav controller), instantiate your custom class 如果您创建一个独立的导航栏(不带导航控制器),请实例化您的自定义类
  • if you create a navigation controller programmatically, you could take advantage of the ObjC runtime. 如果以编程方式创建导航控制器,则可以利用ObjC运行时。

Class switch at runtime: 运行时的类切换:

 #import <objc/runtime.h>
 ...
 object_setClass(theNavController.navigationBar, [CustomNavigationBar class]);

You should also avoid using [UIImage imageNamed:...] each time in drawRect: as it might have an impact on performance (for animations). 您还应该避免在drawRect:每次使用[UIImage imageNamed:...] ,因为这可能会影响性能(对于动画)。 Cache it in an ivar: 将其缓存在一个ivar中:

 if (!bgImage) {
     bgImage = [[UIImage imageNamed:@"NavigationBar.png"] retain];
 }
 [bgImage drawInRect:...];

(and release it in dealloc) (并在dealloc中释放它)

Note: As iOS 5 is still under NDA, I can't mention how you could easily add a background image. 注意:由于iOS 5仍在NDA下,因此我无法提及您如何轻松添加背景图片。 Check out the docs for UINavigationBar. 查看有关UINavigationBar的文档。

Tested Code : 100 % works 测试代码:100%有效

in ur ViewDidLoad 在您的ViewDidLoad中

UIImageView *iv=[[UIImageView alloc]initWithImage:[UIImage imageNamed:@"urNavBarImage.png"]];

self.navigationItem.titleView = iv;

[iv release];

NOTE: urNavBarImage should be exact size of Navigation Bar. 注意: urNavBarImage应该是导航栏的确切大小。 Like this u can change every Viewcontroller Navigation bar. 这样,您可以更改每个Viewcontroller导航栏。

I have created a custom category for UINavigationBar as follows 我为UINavigationBar创建了一个自定义类别,如下所示

UINavigationBar+CustomImage.h

#import <UIKit/UIKit.h>

@interface UINavigationBar (CustomImage)
    - (void) setBackgroundImage:(UIImage*)image;
    - (void) clearBackgroundImage;
    - (void) removeIfImage:(id)sender;
@end

UINavigationBar+CustomImage.m

#import "UINavigationBar+CustomImage.h"

@implementation UINavigationBar (CustomImage)

- (void) setBackgroundImage:(UIImage*)image {
    if (image == NULL) return;
    UIImageView *imageView = [[UIImageView alloc] initWithImage:image];
    imageView.frame = CGRectMake(110,5,100,30);
    [self addSubview:imageView];
    [imageView release];
}

- (void) clearBackgroundImage {
    NSArray *subviews = [self subviews];
    for (int i=0; i<[subviews count]; i++) {
        if ([[subviews objectAtIndex:i]  isMemberOfClass:[UIImageView class]]) {
        [[subviews objectAtIndex:i] removeFromSuperview];
    }
   }    
}

@end

I invoke it from my UINavigationController 我从我的UINavigationController调用它

[[navController navigationBar] performSelectorInBackground:@selector(setBackgroundImage:) withObject:image];

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM