在ios中更改UINavigationBar的背景图像<;5.
对于IOS版本<5,我无法更改在ios中更改UINavigationBar的背景图像<;5.,ios,ios4,Ios,Ios4,对于IOS版本
UINavigationBar
的背景图像。我已经读过一个很好的解决方案,它基于方法swizzling,但这个解决方案的问题是当我添加图像时,它覆盖了所有内容,包括导航栏上的按钮。
我找到了一个部分对我有效的解决方案,它基于以下代码:
@interface UINavigationBar (UINavigationBarCategory)
-(void)setBackgroundImage:(UIImage*)image withTag:(NSInteger)bgTag;
-(void)resetBackground:(NSInteger)bgTag;
@end
@implementation UINavigationBar (UINavigationBarCategory)
-(void)setBackgroundImage:(UIImage*)image withTag:(NSInteger)bgTag{
if(image == NULL){ //might be called with NULL argument
return;
}
UIImageView *aTabBarBackground = [[UIImageView alloc]initWithImage:image];
aTabBarBackground.frame = CGRectMake(0,0,self.frame.size.width,self.frame.size.height);
aTabBarBackground.tag = bgTag;
[self addSubview:aTabBarBackground];
//[self sendSubviewToBack:aTabBarBackground];
[aTabBarBackground release];
}
-(void)setRightButton:(UIButton*)button withTag:(NSInteger)bgTag{
if(button == NULL){ //might be called with NULL argument
return;
}
[self addSubview:button];
}
/* input: The tag you chose to identify the view */
-(void)resetBackground:(NSInteger)bgTag {
[self sendSubviewToBack:[self viewWithTag:bgTag]];
}
@end
我在我的视图中使用了该类别将出现类似以下的方法:
-(void) viewWillAppear:(BOOL)animated {
UIImage *backgroundImage = [UIImage imageNamed:@"background_confernce_import_logo"];
if ([self.navigationController.navigationBar respondsToSelector:@selector(setBackgroundImage:forBarMetrics:)])
{
[self.navigationController.navigationBar setBackgroundImage:backgroundImage forBarMetrics:UIBarMetricsDefault];
}
else{
[[self.navigationController navigationBar] setBackgroundImage:backgroundImage withTag:8675309];
}
}
在else子句中,我调用setBackgroundImage
。这是可以的,但问题是,如果我在第1页的导航栏上有一个右键,然后在返回到第1页后转到第2页,该按钮就会消失。我应该在我的应用程序中的每个页面中更改导航栏的背景图像,就像在我放置新图像的viewwillrespect
方法中这样。
任何帮助都将不胜感激。在IOS 5下没有这样的问题,但它应该在两个版本上都能工作。我不想这么说,但是你的方法(添加一个子视图以保持背景)不会完全按照你提到的原因工作。每次重新绘制导航栏时,子视图将不会保持其z顺序(因此它将覆盖其他UI元素)。此行为由其他来源描述(参见,例如)
如果不想使用swizzling,可以覆盖类别中的drawRect
,以便始终正确绘制背景。(最后一个选项的缺点是,应用程序中的任何导航栏都将使用相同的背景绘制)。这是我使用的示例代码:
@implementation UINavigationBar (CustomBackground)
- (void)drawRect:(CGRect)rect {
UIImage *image = [UIImage imageNamed: @"back.png"];
[image drawInRect:CGRectMake(0, 0, self.frame.size.width, self.frame.size.height)];
}
@end
另一种方法可以是:
子类化UINavigationBar
李>
覆盖drawRect李>
在界面生成器中,将导航栏对象的类设置为UINavigationBar
子类
我还没试过,但它应该能用。根据我的要求,这是我的略带顽皮但不是很完美的黑客。这真的只是为了让OP开心。塞尔吉奥给出了正确的答案
UINavigationBar+CustomDraw.m
NSString *gNavbarBackgroundImageName = @"default_navbar_background.png";
@implementation UINavigationBar (CustomBackground)
- (void)drawRect:(CGRect)rect
{
if (gNavbarBackgroundImageName != nil)
{
UIImage *image = [UIImage imageNamed:gNavbarBackgroundImageName];
[image drawInRect:CGRectMake(0, 0, self.frame.size.width, self.frame.size.height)];
}
}
@end
#import "UINavigationBar+CustomDraw.h"
@implementation FooViewController
- (void)viewWillAppear:(BOOL)animated
{
gNavbarBackgroundImageName = @"foo_navbar_background.png";
[self.navigationController.navigationBar setNeedsDisplay];
}
@end
#import "UINavigationBar+CustomDraw.h"
@implementation BarViewController
- (void)viewWillAppear:(BOOL)animated
{
gNavbarBackgroundImageName = @"bar_navbar_background.png";
[self.navigationController.navigationBar setNeedsDisplay];
}
@end
UINavigationBar+CustomDraw.h
extern NSString *gNavbarBackgroundImageName;
下面是两个视图控制器中的示例用法
FooViewController.m
NSString *gNavbarBackgroundImageName = @"default_navbar_background.png";
@implementation UINavigationBar (CustomBackground)
- (void)drawRect:(CGRect)rect
{
if (gNavbarBackgroundImageName != nil)
{
UIImage *image = [UIImage imageNamed:gNavbarBackgroundImageName];
[image drawInRect:CGRectMake(0, 0, self.frame.size.width, self.frame.size.height)];
}
}
@end
#import "UINavigationBar+CustomDraw.h"
@implementation FooViewController
- (void)viewWillAppear:(BOOL)animated
{
gNavbarBackgroundImageName = @"foo_navbar_background.png";
[self.navigationController.navigationBar setNeedsDisplay];
}
@end
#import "UINavigationBar+CustomDraw.h"
@implementation BarViewController
- (void)viewWillAppear:(BOOL)animated
{
gNavbarBackgroundImageName = @"bar_navbar_background.png";
[self.navigationController.navigationBar setNeedsDisplay];
}
@end
BarViewController.m
NSString *gNavbarBackgroundImageName = @"default_navbar_background.png";
@implementation UINavigationBar (CustomBackground)
- (void)drawRect:(CGRect)rect
{
if (gNavbarBackgroundImageName != nil)
{
UIImage *image = [UIImage imageNamed:gNavbarBackgroundImageName];
[image drawInRect:CGRectMake(0, 0, self.frame.size.width, self.frame.size.height)];
}
}
@end
#import "UINavigationBar+CustomDraw.h"
@implementation FooViewController
- (void)viewWillAppear:(BOOL)animated
{
gNavbarBackgroundImageName = @"foo_navbar_background.png";
[self.navigationController.navigationBar setNeedsDisplay];
}
@end
#import "UINavigationBar+CustomDraw.h"
@implementation BarViewController
- (void)viewWillAppear:(BOOL)animated
{
gNavbarBackgroundImageName = @"bar_navbar_background.png";
[self.navigationController.navigationBar setNeedsDisplay];
}
@end
现在让我们假设您想要显示一个非样式的导航栏,例如在显示Facebook登录页面时(由他们的SDK提供)
使用此选项可防止任何自定义图形:
gNavbarBackgroundImageName = nil;
注意苹果的一些组件在你可能没有想到的地方使用UINavigationBar。例如,MPMoviePlayerController
使用一个自定义导航栏来显示其UI的上部-这将是另一种防止自定义绘图的情况。可能重复@Till,答案可能几乎相同(与您发布的链接相同),但问题略有不同,因为它询问了关于实现自定义背景的具体尝试…@sergio Fair-很有意义。方法swizzling已成为一种禁忌-如果你这样做,苹果将拒绝你的应用程序。此解决方案为每个导航栏只设置一个图像,我需要为每个页面设置不同的图像。正如你在最后一行中提到的。我看到了Sebastian Celis的swizzling方法代码,但它绘制了所有按钮,我希望导航栏中的按钮保持完整。@PetcoYanakiev您可以进一步自定义此方法以使用任何图像。一个快速而肮脏的解决方案可以是包含“当前”所需图像名称的全局NSString。在显示新的视图控制器之前(例如,通过将其推到导航堆栈上),您可以使用所需的名称更新此图像名称。@直到显示一个示例为止。目前,我在SetBackground中放置了一个图像,ViewWillDisplay中的图像将出现。我设法解决了我的代码的问题,我只是在导航栏上添加了添加右按钮的方法,现在可以看到我编辑的代码了。谢谢你的回答。像这样,如果我的导航栏上需要任何自定义元素,我只需要subview和voila。我会尝试你的解决方案,因为我认为它比我的更优雅:)哦,我完全忘了告诉你一些事情-确保你还添加了一些东西来禁用drawRect“hack”因为一旦显示了不应该定制的内容,这可能会严重伤害您。将立即将其添加到我的解决方案中。。。