UIBarButtonItem с пользовательским изображением и без рамки - PullRequest
88 голосов
/ 21 апреля 2010

Я хочу создать UIBarButtonItem с пользовательским изображением, но я не хочу, чтобы граница, которую добавляет iPhone, поскольку у моего изображения есть специальная рамка.

Это то же самое, что кнопка «назад», но кнопка «вперед».

Это приложение для проекта inHouse, поэтому мне все равно, отклонит ли Apple его, одобрит ли он или понравится: -)

Если я использую свойство initWithCustomView: v объекта 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];

Это работает, но если мне придется повторить этот процесс в 10 видах, это не СУХОЙ.

Полагаю, мне нужно подкласс, но что?

  • NSView?
  • UIBarButtonItem?

спасибо,

С уважением,

Ответы [ 9 ]

50 голосов
/ 06 февраля 2012

Другое простое решение -

  1. Перетащите стандартную кнопку UIB
  2. Установите стиль кнопки на пользовательский и установите свое изображение для этой кнопки
  3. Перетащите его на UINavigationBar
  4. Установить селектор
44 голосов
/ 21 апреля 2010

Вы можете добавить метод к 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

Таким образом, в любом месте вашего кода вы можете создать элемент панели, вызывающий этот метод (при условии, что вы включите заголовок в его объявление).

P.S. Вам не нужно использовать 'v' UIView, так как вы можете создать UIBarButtonItem с помощью кнопки в качестве пользовательского представления напрямую.
P.P.S. Вам также нужно [форвард релиз] в вашем коде.

37 голосов
/ 23 декабря 2011

Мне было легко.Это 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;
6 голосов
/ 30 апреля 2011

Альтернативой является подкласс UIBarButtonItem. Зачем? Так что действие вызывается на цели с правильным отправителем. В приведенном выше коде аргумент отправителя в сообщении действия является экземпляром UIButton, а не экземпляром UIBarButtonItem. Это было бы важно, например, если вы хотите представить UIPopoverController из элемента панели кнопок. Подклассифицируя UIBarButtonItem, вы можете добавить ивар, который сохраняет исходную цель, позволяя нашим экземплярам подкласса перехватывать, изменять и пересылать сообщение действия с соответствующим отправителем.

Итак, 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
4 голосов
/ 02 апреля 2014
UIBarButtonItem *menuItem = [[UIBarButtonItem alloc] initWithImage: [UIImage imageNamed:@"icon-menu.png"]
                                                                    style:UIBarButtonItemStylePlain
                                                                   target:self
                                                                   action:@selector(showMenu)];
3 голосов
/ 09 апреля 2013

Это также может быть сделано программно (конечно):

Сначала создайте пользовательский вид. Этот пользовательский вид может содержать изображение, кнопку или все, что вы хотели бы. Пользовательский вид может быть выполнен программно или в 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 голос
/ 08 августа 2013

Проверьте это простое решение.

- (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 - прозрачное png-изображение размером 1 пиксель, которое вы можете скачать по ссылке ниже

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

1 голос
/ 29 ноября 2012

Хорошо, эта категория работает очень хорошо, потому что с 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
0 голосов
/ 19 июля 2013

Еще одно решение, подумайте, что проще при программировании кнопки:

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];
...