如何为UIToolbar使用不同的多个类别?

时间:2011-09-01 17:31:35

标签: iphone objective-c cocoa-touch uitoolbar objective-c-category

我的应用程序中有一些UIToolbars。我希望每个人都有不同的背景。这是我有一个类别的例子:

#import "UIToolbar+NavBarAdditions.h"


@implementation UIToolbar (Addition)
- (void) drawRect:(CGRect)rect {
    UIImage *barImage = [UIImage imageNamed:@"rowbg.png"];
    [barImage drawInRect:rect];
}
@end

我有一些图像rowbg1,rowbg2等我想用于我的应用程序内的其他UIToolbars。如何选择用于相应工具栏的类别?

3 个答案:

答案 0 :(得分:3)

更改工具栏背景

使用子类

类别会更改所有UIToolbar类。如果您需要不同的工具栏,请让每个客户负责设置图像:

@interface UIBgToolbar : UIToolbar {
@private
    UIImage *_background;
}
@end
@implementation UIBgToolbar
- (id)initWithFrame:(CGRect)aRect imagen:(UIImage*)image {
    if (self = [super initWithFrame:aRect]){
        _background = [image retain];
    }
    return self;
}
- (void) drawRect:(CGRect)rect {
    UIImage *barImage = _background;
    [barImage drawInRect:rect];
}
-(void)dealloc {
    [_background release];
    [super dealloc];
}
@end

用法:

UIImage *bg = [UIImage imageNamed:@"bar_bottom.png"];
// 416 = 480 - status bar (20) - navigation bar (44)
CGRect rect = CGRectMake(0, 416-bg.size.height, bg.size.width, bg.size.height);
UIBgToolbar *toolbar = [[UIBgToolbar alloc] initWithFrame:rect imagen:bg];
[self.view addSubview:toolbar];
[toolbar release];

使用子视图

这是添加子视图并且不需要子类或类别的替代方法:

UIImage *bg = [UIImage imageNamed:@"bar_bottom.png"];
// 416 = 480 - status bar (20) - navigation bar (44)
CGRect rect = CGRectMake(0, 416-bg.size.height, bg.size.width, bg.size.height);
UIToolbar *toolbar = [[UIToolbar alloc] initWithFrame:rect];

UIImageView *background = [[[UIImageView alloc] initWithImage:bg] autorelease];
background.frame = toolbar.bounds;
background.autoresizingMask = UIViewAutoresizingFlexibleWidth;
BOOL isIOS5 = [[[UIDevice currentDevice] systemVersion] intValue] >= 5;
toolbar insertSubview:background atIndex: (isIOS5 ? 1 : 0)];

[self.view addSubview:toolbar];
[toolbar release];

使背景透明。

除非你真的需要透明的背景,否则不要使用它。

@interface UITransparentToolBar : UIToolbar
@end
@implementation UITransparentToolBar
- (void)drawRect:(CGRect)rect {
    [[UIColor clearColor] set];
    CGContextFillRect(UIGraphicsGetCurrentContext(), rect);
}
@end

用法:

// create the toolbar
UIImage *bg = [UIImage imageNamed:@"bar_bottom.png"];
// 416 = 480 - status bar (20) - navigation bar (44)
CGRect rect = CGRectMake(0, 416-bg.size.height, bg.size.width, bg.size.height);
UIBgToolbar *toolbar = [[UIBgToolbar alloc] initWithFrame:rect];

// add the background
// self.backgroundColor = [UIColor clearColor];
UIImageView *background = [[UIImageView alloc] initWithImage:bg];
background.frame = toolbar.bounds;
background.autoresizingMask = UIViewAutoresizingFlexibleWidth;
BOOL isIOS5 = [[[UIDevice currentDevice] systemVersion] intValue] >= 5;
[toolbar insertSubview:background atIndex: (isIOS5 ? 1 : 0)];

[self.view addSubview:toolbar];
[toolbar release];

更改导航栏

导航栏背景

在类别中使用诺亚的代码。

也可以使用子类:

  • 从Noah的答案中创建一个包含drawRect方法的UINavigationToolbar子类。 - 选择您的MainWindow.XIB,选择“导航栏”,按⌥⌘3(显示Identity Inspector),然后将班级更改为您刚刚创建的班级。
  • 同样在IB中,按⌥⌘4(显示属性检查器)并在字段标记中设置一个数字。如果你查看诺亚的代码,那么这个数字就决定使用哪个图像。

导航栏工具栏背景

与普通工具栏相同但使用类别,因为导航工具栏是只读的:

// UIToolbar.h
@interface UIToolbar (Transparency)
- (void)drawRect:(CGRect)rect;
@end
// UIToolbar.m
#import "TransparentToolbar.h"
@implementation UIToolbar (Transparency)
- (void)drawRect:(CGRect)rect {
    [[UIColor clearColor] set];
    CGContextFillRect(UIGraphicsGetCurrentContext(), rect);
}
@end

用法:

// bar_bottom_bumped.png is a toolbar image with transparency
UIImage *bg = [UIImage imageNamed:@"bar_bottom_bumped.png"];
UIImageView *background = [[UIImageView alloc] initWithImage:bg];
background.frame = self.navigationController.toolbar.bounds;
background.autoresizingMask = UIViewAutoresizingFlexibleWidth;
BOOL isIOS5 = [[[UIDevice currentDevice] systemVersion] intValue] >= 5;
self.navigationController.toolbar.backgroundColor = [UIColor clearColor];
[self.navigationController.toolbar insertSubview:background atIndex: (isIOS5 ? 1 : 0)];

答案 1 :(得分:2)

如果你自己在IB或通过代码创建工具栏,那么Jano的解决方案大多是正确的,尽管我不同意使其透明的想法:你应该避免做不必要的混合。但是,如果需要替换导航控制器创建的工具栏,则需要使用类别而不是子类。您可以使用现有的实施;您只需要在每个要使用不同外观的工具栏上设置不同的tag,然后在-drawRect:中检查该值。换句话说,您的视图控制器应该具有以下内容:

- (void)viewWillAppear:(BOOL)animated
{
    [super viewWillAppear:animated];
    UIToolbar *toolbar = self.navigationController.toolbar;
    toolbar.tag = 3; // different value for each controller, or however you want to choose the toolbar
    [toolbar setNeedsDisplay];
}

并且您的工具栏类别应该是这样的:

- (void)drawRect:(CGRect)r
{
    UIImage *barImage = nil;
    switch(self.tag)
    {
        case 1:
            barImage = [UIImage imageNamed:@"rowbg.png"];
            break;
        case 3:
            barImage = [UIImage imageNamed:@"something else.png"];
            break;
    }

    [barImage drawInRect:self.bounds];
}

答案 2 :(得分:1)

您应该使用子类化而不是类别