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

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-30 17:09:40  来源:igfitidea点击:

UIBarButtonItem with custom image and no border

iosiphoneuibarbuttonitem

提问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 UIBarButtonItemwith 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

另一个简单的解决方案是

  1. Drag a standard UIButton
  2. Set the button's style to custom and set your image for that button
  3. Drag it onto the UINavigationBar
  4. Set Selector
  1. 拖动一个标准的 UIButton
  2. 将按钮的样式设置为自定义并为该按钮设置图像
  3. 将其拖到 UINavigationBar 上
  4. 设置选择器

回答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 图像,您可以从下面的链接下载

http://commons.wikimedia.org/wiki/File:1x1.png

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