具有自定义图像且没有边框的UIBarButtonItem


89

我想用自定义图像创建UIBarButtonItem,但是我不希望iPhone添加边框,因为我的图像有特殊边框。

它与后退按钮相同,但前进按钮相同。

这个程序是针对内部项目的,所以我不在乎苹果是否拒绝或批准它或喜欢它:-)

如果我使用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个视图中重复此过程,则此操作不是DRY。

我想我必须继承,但是呢?

  • NSView?
  • UIBarButtonItem?

谢谢,

问候,


3
感谢您分享您的代码,这就是我所需要的:)。
马克斯

1
所有人,我都使用了San在2月6日提供的答案。花了5分钟全部时间将其集成到我的Storyboard中,并且运行良好。选择器属性位于IB的连接检查器中。将控件从UIButton拖动到ViewController对象,然后将弹出方法。点击您想要的方法,您几乎完成了。剩下的唯一事情就是一些代码清理。使用btnXXXXX.hidden隐藏和取消隐藏以替换barbuttonitem = nil。但是这种方法很简单而且很干净。
user589642

Answers:


44

您可以将方法添加到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

因此,您可以在代码中的任何位置创建调用此方法的条形项(前提是您在其声明中包含标头)。

PS您不需要使用“ v” UIView,因为可以UIBarButtonItem直接使用按钮创建为自定义视图。
PPS您的代码中也需要[向前发布]。


自定义类别:我必须使用这些声明创建头文件,并在实现文件中放置要引用的代码?谢谢
mongeta

它的工作很多,但是我不能写选择器,我不想在类别上写选择器,我怎么能在我的课堂上写它
Nilesh Tupe

@NileshTupe是什么意思?您传递选择器方法目标-目标可以是您想要的任何对象
普京

2
顺便说一句,我将此添加到我的UIKit便利类别的小型开放源代码仓库中。感谢@Vladimir的启发。(请注意,我所有的东西都是基于ARC的) github.com/egold/UIKitConvenience/blob/master/UIKitConvenience/…–
Eric Goldberg,

50

另一个简单的解决方案是

  1. 拖动一个标准的UIButton
  2. 将按钮的样式设置为自定义,然后为该按钮设置图像
  3. 将其拖动到UINavigationBar上
  4. 集合选择器

可能是最简单的解决方案。谢谢!
Prine

1
辉煌!唯一的怪癖-如果直接将按钮拖动到导航栏,它将不起作用。在将按钮添加到导航栏之前,必须将其设置为自定义。不知道为什么,但这就是事实。因此,步骤1-意味着将UIBatton拖动到用户界面上除导航栏之外的其他位置。
Andrei Tchijov 2013年

很难简单有效。好的答案
Add080bbA 2014年

37

我发现这很容易。它被放在最上面。“ 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;

6

另一种方法是子类化UIBarButtonItem。为什么?以便使用正确的发送者在目标上调用该操作。在上面的代码中,操作消息中的sender参数是UIButton实例,而不是UIBarButtonItem实例。例如,如果您希望通过条形按钮项显示UIPopoverController,这将很重要。通过对UIBarButtonItem进行子类化,您可以添加一个保留原始目标的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

5
UIBarButtonItem *menuItem = [[UIBarButtonItem alloc] initWithImage: [UIImage imageNamed:@"icon-menu.png"]
                                                                    style:UIBarButtonItemStylePlain
                                                                   target:self
                                                                   action:@selector(showMenu)];

3

这当然也可以通过编程(当然)来完成:

首先,创建一个自定义视图。该自定义视图可以包含图像,按钮或您想要的任何其他内容。可以通过编程方式或在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];

接下来,创建一个UIBarButtonItem并使用自定义视图对其进行初始化。

UIBarButtonItem *customBarButtonItem = [[UIBarButtonItem alloc] initWithCustomView:customView];

现在,只需将自定义UIBarButton添加到leftBarButtonItem中:

self.navigationItem.leftBarButtonItem = customBarButtonItem;

1

好的,该类别非常有效,因为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

1

检查这个简单的解决方案。

- (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;
}

这里1x1.png是一个1像素的透明png图像,您可以从下面的链接下载

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


您可以只使用[UIImage new]而不是使用透明图像。
詹姆斯·坎贝尔

0

另一种解决方案是,以编程方式创建按钮的情况认为更简单:

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];
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.