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

  1. 拖动一个标准的UIButton
  2. 将button的样式设置为自定义,并为该button设置图像
  3. 将其拖到UINavigationBar上
  4. 设置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图像,你可以从下面的链接下载

http://commons.wikimedia.org/wiki/File:1×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];