ios 带有自定义图像且无边框的 UIBarButtonItem
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/2681321/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
UIBarButtonItem with custom image and no border
提问by mongeta
I want to create a UIBarButtonItem with a custom image, but I don't want the border that iPhone adds, as my Image has a special border.
我想创建一个带有自定义图像的 UIBarButtonItem,但我不想要 iPhone 添加的边框,因为我的图像有一个特殊的边框。
It's the same as the back button but a forward button.
它与后退按钮相同,但是是前进按钮。
This App is for an inHouse project, so I don't care if Apple reject or approves it or likes it :-)
此应用程序用于内部项目,因此我不在乎 Apple 是否拒绝或批准或喜欢它 :-)
If I use the initWithCustomView:v property of the UIBarButtonItem, I can do it:
如果我使用initWithCustomView:对的UIBarButtonItem诉的财产,我可以做到这一点:
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];
This works, but if I have to repeat this process in 10 views, this is not DRY.
此作品,但如果我不得不重复这个过程10次,这是不干燥。
I suppose I have to subclass, but what ?
我想我必须子类化,但是什么?
- NSView ?
- UIBarButtonItem ?
- NSView ?
- UIBarButtonItem ?
thanks,
谢谢,
regards,
问候,
采纳答案by Vladimir
You can add a method to UIBarButtonItem without subclassing it using custom category:
您可以向 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
So anywhere in your code you can create bar item calling this method (provided that you include a header with its declaration).
因此,您可以在代码中的任何位置创建调用此方法的栏项(前提是您在其声明中包含一个标头)。
P.S. You do not need to use 'v' UIView as you can create UIBarButtonItem
with a button as custom view directly.
P.P.S. You also need [forward release] in your code.
PS 您不需要使用 'v' UIView,因为您可以UIBarButtonItem
使用按钮直接创建自定义视图。
PPS 您的代码中还需要 [forward release]。
回答by san
Another simple solution is
另一个简单的解决方案是
- Drag a standard UIButton
- Set the button's style to custom and set your image for that button
- Drag it onto the UINavigationBar
- Set Selector
- 拖动一个标准的 UIButton
- 将按钮的样式设置为自定义并为该按钮设置图像
- 将其拖到 UINavigationBar 上
- 设置选择器
回答by m-farhan
I found it this ways easy. It is sugested on top. "random.png" has to be in project. Just drag and drop any image.
我发现这很容易。它是在顶部 sugested。“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;
回答by FluffulousChimp
An alternative is to subclass UIBarButtonItem. Why? So that the action is invoked on the target with the correct sender. In the code above, the sender argument in the action message is the UIButton instance, not the UIBarButtonItem instance. This would be important, for example, if you wish to present a UIPopoverController from the bar button item. By subclassing UIBarButtonItem, you can add an ivar that retains the original target, allowing our subclass instances to intercept, modify, and forward the action message with the proper sender.
另一种方法是继承 UIBarButtonItem。为什么?以便使用正确的发送者在目标上调用操作。在上面的代码中,动作消息中的 sender 参数是 UIButton 实例,而不是 UIBarButtonItem 实例。这很重要,例如,如果您希望从栏按钮项中显示一个 UIPopoverController。通过子类化 UIBarButtonItem,您可以添加一个保留原始目标的 ivar,允许我们的子类实例拦截、修改和转发具有适当发送者的操作消息。
So, CCFBarButtonItem.h:
所以,CCFBarButtonItem.h:
#import <uIKit/UIBarButtonItem.h>
@interface CCFBarButtonItem : UIBarButtonItem
{
@protected
id _originalTarget;
}
- (id)initWithImage:(UIImage *)image target:(id)target action:(SEL)action;
@end
and CCFBarButtonItem.m
和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
回答by alexmorhun
UIBarButtonItem *menuItem = [[UIBarButtonItem alloc] initWithImage: [UIImage imageNamed:@"icon-menu.png"]
style:UIBarButtonItemStylePlain
target:self
action:@selector(showMenu)];
回答by abriggs
This can also be done programmatically as well (of-course):
这也可以以编程方式完成(当然):
First, create a custom view. This custom view can contain an image, button or whatever else you would like. The custom view can be made programmatically or in IB:
首先,创建一个自定义视图。此自定义视图可以包含图像、按钮或您想要的任何其他内容。自定义视图可以以编程方式或在 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];
Next, create a UIBarButtonItem and initialize it with the custom view.
接下来,创建一个 UIBarButtonItem 并使用自定义视图对其进行初始化。
UIBarButtonItem *customBarButtonItem = [[UIBarButtonItem alloc] initWithCustomView:customView];
Now, just add the custom UIBarButton to the leftBarButtonItem:
现在,只需将自定义 UIBarButton 添加到 leftBarButtonItem:
self.navigationItem.leftBarButtonItem = customBarButtonItem;
回答by Fremy Jose
Check this out simple solution.
看看这个简单的解决方案。
- (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;
}
Here 1x1.png is a 1 pixel transparent png image which you can download from the link below
这里的 1x1.png 是一个 1 像素的透明 png 图像,您可以从下面的链接下载
回答by Raegtime
Ok that category works very good because there are no problems with Popovercontroller :-)
好的,该类别效果很好,因为 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
回答by Mikhail
One another solution, think it's simpler in case when creating button programatically:
另一种解决方案,认为在以编程方式创建按钮的情况下更简单:
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];