UIBarButtonItem与自定义图像和无边框
我想创build一个自定义图像的UIBarButtonItem,但我不希望iPhone添加的边框,因为我的图像有一个特殊的边框。
它与后退button相同,但是是前进button。
这个应用程序是一个inHouse项目,所以我不在乎苹果拒绝或批准它或喜欢它:-)
如果我使用UIBarButtonItem的initWithCustomView:v属性,我可以这样做:
UIImage *image = [UIImage imageNamed:@"right.png"]; UIButton *button = [UIButton buttonWithType:UIButtonTypeCustom]; [button setBackgroundImage: [image stretchableImageWithLeftCapWidth:7.0 topCapHeight:0.0] forState:UIControlStateNormal]; [button setBackgroundImage: [[UIImage imageNamed: @"right_clicked.png"] stretchableImageWithLeftCapWidth:7.0 topCapHeight:0.0] forState:UIControlStateHighlighted]; button.frame= CGRectMake(0.0, 0.0, image.size.width, image.size.height); [button addTarget:self action:@selector(AcceptData) forControlEvents:UIControlEventTouchUpInside]; UIView *v=[[UIView alloc] initWithFrame:CGRectMake(0.0, 0.0, image.size.width, image.size.height) ]; [v addSubview:button]; UIBarButtonItem *forward = [[UIBarButtonItem alloc] initWithCustomView:v]; self.navigationItem.rightBarButtonItem= forward; [v release]; [image release];
这是有效的,但是如果我必须在10个视图中重复这个过程,这不是干的。
我想我必须inheritance,但是什么?
- NSView?
- UIBarButtonItem?
谢谢,
问候,
你可以添加一个方法到UIBarButtonItem而不用使用自定义类别进行子类化:
@interface UIBarButtonItem(MyCategory) + (UIBarButtonItem*)barItemWithImage:(UIImage*)image target:(id)target action:(SEL)action; @end @implementation UIBarButtonItem(MyCategory) + (UIBarButtonItem*)barItemWithImage:(UIImage*)image target:(id)target action:(SEL)action{ // Move your item creation code here } @end
因此,在代码中的任何地方,您都可以创build调用此方法的栏项(只要您的声明中包含头)。
PS您不需要使用' UIBarButtonItem
,因为您可以UIBarButtonItem
使用button作为自定义视图来创buildUIBarButtonItem
。
PPS您还需要在代码中使用[forward release]。
另一个简单的解决scheme
- 拖动一个标准的UIButton
- 将button的样式设置为自定义,并为该button设置图像
- 将其拖到UINavigationBar上
- 设置select器
我发现这种方式很容易。 它被顶上。 “random.png”必须在项目中。 只需拖放任何图像。
UIButton *a1 = [UIButton buttonWithType:UIButtonTypeCustom]; [a1 setFrame:CGRectMake(0.0f, 0.0f, 25.0f, 25.0f)]; [a1 addTarget:self action:@selector(randomMsg) forControlEvents:UIControlEventTouchUpInside]; [a1 setImage:[UIImage imageNamed:@"config.png"] forState:UIControlStateNormal]; UIBarButtonItem *random = [[UIBarButtonItem alloc] initWithCustomView:a1]; //? line incomplete ?// imageNamed:@"random.png"] style:UIBarButtonItemStylePlain target:self action:@selector(randomMsg)]; self.navigationItem.rightBarButtonItem = random;
另一种方法是inheritanceUIBarButtonItem。 为什么? 所以这个动作是用正确的发送者在目标上调用的。 在上面的代码中,动作消息中的sender参数是UIButton实例,而不是UIBarButtonItem实例。 这很重要,例如,如果您希望从条形button项呈现UIPopoverController。 通过inheritanceUIBarButtonItem,可以添加一个保留原始目标的ivar,从而允许我们的子类实例拦截,修改和转发具有正确发送者的动作消息。
所以,CCFBarButtonItem.h:
#import <uIKit/UIBarButtonItem.h> @interface CCFBarButtonItem : UIBarButtonItem { @protected id _originalTarget; } - (id)initWithImage:(UIImage *)image target:(id)target action:(SEL)action; @end
和CCFBarButtonItem.m
#import "CCFBarButtonItem.h" #import <UIKit/UIButton.h> #import <UIKit/UIView.h> #import <UIKit/UIImage.h> @implementation CCFBarButtonItem #pragma mark - Object life cycle - (id)initWithImage:(UIImage *)image target:(id)target action:(SEL)action; { _ASSIGN( _originalTarget, target ); UIButton *imgButton = [UIButton buttonWithType:UIButtonTypeCustom]; [imgButton setImage:image forState:UIControlStateNormal]; imgButton.frame = CGRectMake(0.0, 0.0, image.size.width, image.size.height); [imgButton addTarget:self action:action forControlEvents:UIControlEventTouchUpInside]; self = [super initWithCustomView:imgButton]; return self; } - (void)dealloc; { MCRelease(_originalTarget); [super dealloc]; } - (NSMethodSignature *)methodSignatureForSelector:(SEL)aSelector; { if( [_originalTarget respondsToSelector:aSelector] ) { return [_originalTarget methodSignatureForSelector:aSelector]; } else { return [super methodSignatureForSelector:aSelector]; } } - (void)forwardInvocation:(NSInvocation *)anInvocation; { SEL aSelector = [anInvocation selector]; if( [_originalTarget respondsToSelector:aSelector] ) { // modify the 'sender' argument so that it points to self [anInvocation setArgument:&self atIndex:2]; [anInvocation invokeWithTarget:_originalTarget]; } else { [self doesNotRecognizeSelector:aSelector]; } } @end
UIBarButtonItem *menuItem = [[UIBarButtonItem alloc] initWithImage: [UIImage imageNamed:@"icon-menu.png"] style:UIBarButtonItemStylePlain target:self action:@selector(showMenu)];
这也可以以编程方式完成(当然):
首先,创build一个自定义视图。 这个自定义视图可以包含一个图像,button或任何你想要的。 自定义视图可以以编程方式或在IB中进行:
UIImage *customImage = [UIImage imageNamed:@"imageName"]; UIView *customView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, customImage.size.width, customImage.size.height)]; customView.backgroundColor = [UIColor colorWithPatternImage:customImage];
接下来,创build一个UIBarButtonItem并使用自定义视图进行初始化。
UIBarButtonItem *customBarButtonItem = [[UIBarButtonItem alloc] initWithCustomView:customView];
现在,只需将自定义UIBarButton添加到leftBarButtonItem:
self.navigationItem.leftBarButtonItem = customBarButtonItem;
确定该类别工作得很好,因为Popovercontroller没有问题:-)
#import <UIKit/UIKit.h> @interface UIBarButtonItem (BarButtonItemExtended) + (UIBarButtonItem*)barItemWithImage:(UIImage*)image target:(id)target action:(SEL)action; -(void)performBarButtonAction:(id)sender; @end #import "UIBarButtonItem+BarButtonItemExtended.h" @implementation UIBarButtonItem (BarButtonItemExtended) + (UIBarButtonItem*)barItemWithImage:(UIImage*)image target:(id)target action:(SEL)action { UIButton *imgButton = [UIButton buttonWithType:UIButtonTypeCustom]; [imgButton setImage:image forState:UIControlStateNormal]; imgButton.frame = CGRectMake(0.0, 0.0, image.size.width, image.size.height); UIBarButtonItem *b = [[UIBarButtonItem alloc]initWithCustomView:imgButton]; [imgButton addTarget:b action:@selector(performBarButtonAction:) forControlEvents:UIControlEventTouchUpInside]; [b setAction:action]; [b setTarget:target]; return b; } -(void)performBarButtonAction:(UIButton*)sender { [[self target] performSelector:self.action withObject:self]; } @end
看看这个简单的解决scheme。
- (void)splitViewController:(UISplitViewController *)splitController willHideViewController:(UIViewController *)viewController withBarButtonItem:(UIBarButtonItem *)barButtonItem forPopoverController:(UIPopoverController *)popoverController { barButtonItem.image = [UIImage imageNamed:@"navButton.png"]; barButtonItem.style = UIBarButtonItemStylePlain; [barButtonItem setBackgroundImage:[UIImage imageNamed:@"1x1.png"] forState:UIControlStateNormal barMetrics:UIBarMetricsDefault]; [self.navigationItem setLeftBarButtonItem:barButtonItem animated:YES]; self.masterPopoverController = popoverController; }
这里1×1.png是一个1像素的透明PNG图像,你可以从下面的链接下载
另一个解决scheme,认为这是更简单的情况下,编程方式创buildbutton时:
UIBarButtonItem *button = [[UIBarButtonItem alloc] initWithImage:defaultImage landscapeImagePhone:landscapeImage style:UIBarButtonItemStylePlain target:self action:@selector(someSelector)]; [button setBackgroundImage:[UIImage new] forState:UIControlStateNormal barMetrics:UIBarMetricsDefault]; [button setBackgroundImage:[UIImage new] forState:UIControlStateNormal barMetrics:UIBarMetricsLandscapePhone];