Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/sorting/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在ios中更改UINavigationBar的背景图像<;5._Ios_Ios4 - Fatal编程技术网

在ios中更改UINavigationBar的背景图像<;5.

在ios中更改UINavigationBar的背景图像<;5.,ios,ios4,Ios,Ios4,对于IOS版本

对于IOS版本<5,我无法更改
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”因为一旦显示了不应该定制的内容,这可能会严重伤害您。将立即将其添加到我的解决方案中。。。