【问题标题】:Custom UINavigationController UIToolbar Background Image自定义 UINavigationController UIToolbar 背景图片
【发布时间】:2011-03-15 17:33:04
【问题描述】:

我有一个使用UINavigationController 的iPhone 应用程序,并希望使用自定义背景图像自定义元素。我可以很容易地使用以下 Objective-C 类别为 UINavigationController's UINavigationBar 做到这一点:

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

我想对 UINavigationController's UIToolbar 做同样的事情,但同样的方法似乎不起作用(尽管我完全不知道为什么不这样做。)我环顾四周,人们似乎建议子类化UIToolbar,但这对于UINavigationController's 工具栏是不可能的,它是一个只读的UIToolbar。我想使用UINavigationController's 工具栏而不是仅仅制作子视图工具栏,因为我正在使用滑入式setToolbarHidden 动画。

任何人都知道是否可以将背景图像应用到这个UINavigationController 工具栏(很可能通过某种方式覆盖drawRect 方法)?

【问题讨论】:

    标签: objective-c cocoa-touch uinavigationcontroller uitoolbar


    【解决方案1】:

    更新:

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


    另一种方法是简单地为您的应用程序的UINavigationBar 类创建一个类别。这很容易实现:

    界面:

    @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

    【讨论】:

    • 不幸的是,这自定义了导航栏而不是工具栏。
    • 哇,好点子。我完全错过了这个标记。不过对于导航栏来说仍然是一个很好的解决方案:)
    • 我在我的代码中添加了两个文件 UINavigationBar.h 和 UINavigationBar.m 并将此代码添加到它们。我还尝试使用文件名 JHNavigationBar.h/.m。它不是自动为我申请的。我错过了什么?
    • @joshholat 你只运行 iOS 5.0+ 吗?如果是这样你需要使用 UIAppearance 来自定义。这仅适用于 5.0 之前的版本。
    • @joshholat 您是否在使用接口文件时包含了它?只是将文件添加到项目中并不意味着它会被使用。请务必在您希望使用它的地方#import。
    【解决方案2】:

    您需要子类化而不是创建类别。

    我不太清楚为什么一个类别适用于 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。我发现最简单的方法是在 Interface Builder 中选择导航控制器,然后在 Attributes Inspector 中选中“Shows Toolbar”框。工具栏应显示在NavigationController 窗口中。单击它,然后在 Identity Inspector 中将类更改为 MyToolbar

    【讨论】:

    • 太棒了!谢谢。您(或其他任何人)是否知道以编程方式完成最后一步的方法?我没有使用 Interface Builder 设置导航控制器。
    • @Chris,我也想知道如何以编程方式覆盖工具栏。谢谢!
    • 在另一个 SO 问题中提出/回答,因为我需要知道:stackoverflow.com/a/15767291/1106878
    【解决方案3】:

    最好的解决方案之一是创建 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 用于自定义 BackgroundImage 结果如下:

    @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
    

    你好!

    【讨论】:

      【解决方案4】:

      一个简单的选择是继承 UINavigationBar/UIToolbar 并使用以下方法初始化导航控制器:

      - (instancetype)initWithNavigationBarClass:(Class)navigationBarClass toolbarClass:(Class)toolbarClass

      但是,对于简单的自定义(如背景图像、阴影等),我建议使用UIAppearance 协议模式。

      【讨论】:

        猜你喜欢
        • 2011-03-14
        • 1970-01-01
        • 2011-09-11
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多