自定义UINavigationController工具栏背景图片

16
我有一个使用UINavigationController的 iPhone 应用程序,想要使用自定义背景图像来定制元素。我能够使用 Objective-C 类别轻松地为UINavigationController's UINavigationBar 进行此操作,如下所示:

http://foobarpig.com/iphone/uinavigationbar-with-solid-color-or-image-background.html

我想为UINavigationController's UIToolbar 做同样的事情,但是相同的方法似乎不起作用(尽管我绝对不知道为什么)。我查找了一些资料,人们似乎建议对UIToolbar进行子类化,但这对于只读的UINavigationController工具栏不可能。我想使用UINavigationController's 工具栏,而不仅仅是创建一个子视图工具栏,因为我正在使用滑入的setToolbarHidden 动画。
有没有人知道是否可以将背景图像应用于此UINavigationController 工具栏(最可能是通过覆盖drawRect方法)?
4个回答

10

更新:

在iOS 5.0+中,你现在可以使用 UIAppearance 自定义导航栏。


另一种方法是为你的应用程序的 UINavigationBar 类创建一个分类(Category)。这很容易实现:

接口:

@interface UINavigationBar (TENavigationBar)

- (void) drawRect:(CGRect)rect;

@end

实现:

@implementation UINavigationBar (TENavigationBar)

- (void) drawRect:(CGRect)rect
{
    UIImage *image = [UIImage imageNamed:@"navigation_background"];

    [image drawInRect:CGRectMake(0, 
                                 0, 
                                 self.frame.size.width, 
                                 self.frame.size.height)];
}

@end

那么这将会被 全局地 自动应用到所有的 UINavigationBar 上。


1
不幸的是,这个定制化只针对导航栏而非工具栏。 - Oliver Pearmain
哇,好主意。我完全错过了这个点。不过对于导航栏来说仍然是一个不错的解决方案 :) - Maurizio
我在我的代码中添加了两个文件,UINavigationBar.h和UINavigationBar.m,并添加了以下代码。我还尝试使用文件名JHNavigationBar.h/.m。但它没有自动应用到我的项目中。我错过了什么吗? - joshholat
1
@joshholat 你只在运行iOS 5.0+吗?如果是的话,你需要使用UIAppearance来自定义。这仅适用于5.0之前的版本。 - Maurizio
1
@joshholat 你在使用的地方是否包含了接口文件?仅仅将文件添加到项目中并不意味着它会被使用。请确保在需要使用它的地方进行 #import。 - Eric G

9
你需要创建子类而不是创建一个分类。
我不确定为什么对于导航栏 UINavigationBar 创建一个分类可以运作,但对于工具栏 UIToolbar 却行不通。但是,对于两者都可行的方式是创建子类,这也是更加标准的自定义方法。
因此,如果要创建 UIToolbar 的子类,请创建一个名为 MyToolbar(或类似名称)的类,并将以下内容放入 .h 文件中:
#import <UIKit/UIKit.h>
#import <Foundation/Foundation.h>

@interface MyToolbar : UIToolbar {}

- (void)drawRect:(CGRect)rect;

@end

这是在.m文件中的代码:

#import "MyToolbar.h"

@implementation MyToolbar

- (void)drawRect:(CGRect)rect {
    backgroundImage = [UIImage imageNamed:@"my-awesome-toolbar-image.png"];
    [backgroundImage drawInRect:CGRectMake(0, 0, self.frame.size.width, self.frame.size.height)];
}

@end

然后,您需要告诉导航控制器使用MyToolbar而不是UIToolbar。我发现最简单的方法是在界面构建器中选择导航控制器,然后在属性检查器中选中“显示工具栏”框。工具栏应该会出现在NavigationController窗口中。点击它,然后在标识检查器中将类更改为MyToolbar


3
好的!谢谢。你(或其他人)知道如何通过编程方式完成最后一步吗?我没有使用Interface Builder设置我的导航控制器。 - Chris
2
@Chris,我也想知道如何通过编程方式覆盖工具栏。谢谢! - pixelfreak
由于我需要知道,所以在另一个SO问题中提出/回答:http://stackoverflow.com/a/15767291/1106878 - sbonami

2

最好的解决方案之一是创建一个UINavigationBar和UIToolbar类别。下面的类提供了iOS 4.0和iOS 5.0兼容的解决方案:

唯一需要做的是在你的viewDidLoad中调用下面的方法:

// Customizacion de navigation bar y toolbar compatible con iOS4 e iOS5
[UINavigationBar iOS5UINavigationBarBackgroundImage];
[UIToolbar iOS5UIToolbarBackgroundImage];    

因此,适用于iOS 4.0和iOS 5.0兼容性的类别Category可自定义背景图像结果如下:

@implementation UINavigationBar (BackgroundImage)
- (void)drawRect:(CGRect)rect 
{    
    UIImage* img = [UIImage imageNamed: @"navigation-bg.png"];
    [img drawInRect: CGRectMake(0, 0, self.frame.size.width, self.frame.size.height)];  
    [self setTintColor:UIColorFromRGB(0x5ca666)];      
}
+ (void) iOS5UINavigationBarBackgroundImage
{
    if ([UINavigationBar respondsToSelector: @selector(appearance)])
    {
        [[UINavigationBar appearance] setBackgroundImage: [UIImage imageNamed: @"navigation-bg.png"] forBarMetrics: UIBarMetricsDefault];
        [[UINavigationBar appearance] setTintColor:UIColorFromRGB(0x5ca666)];
    }
}
@end

@implementation UIToolbar (BackgroundImage)
- (void)drawRect:(CGRect)rect 
{
    UIImage *image = [UIImage imageNamed: @"toolbar-bg.png"];
    [image drawInRect:CGRectMake(0, 0, self.frame.size.width, self.frame.size.height)];
    [self setTintColor:UIColorFromRGB(0x5ca666)];
}
+ (void) iOS5UIToolbarBackgroundImage
{
    if ([UIToolbar respondsToSelector: @selector(appearance)])
    {
        [[UIToolbar appearance] setBackgroundImage:[UIImage imageNamed: @"toolbar-bg.png"] forToolbarPosition:UIToolbarPositionAny barMetrics:UIBarMetricsDefault];
        [[UIToolbar appearance] setTintColor:UIColorFromRGB(0x5ca666)];
    }
}
@end

你好!


0
一个简单的选项是子类化UINavigationBar/UIToolbar并使用以下方法初始化导航控制器: - (instancetype)initWithNavigationBarClass:(Class)navigationBarClass toolbarClass:(Class)toolbarClass
但是,对于简单的自定义(如背景图片,阴影等),我建议使用UIAppearance协议模式。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接