UIBarButtonItem із власним зображенням і без меж


89

Я хочу створити UIBarButtonItem із власним зображенням, але не хочу, щоб додавала межа, яку додає iPhone, оскільки мій Image має спеціальну межу.

Це те саме, що кнопка назад, але кнопка вперед.

Цей додаток призначений для проекту 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?

Дякую,

з повагою,


3
Дякую, що поділилися своїм кодом, це все, що мені потрібно :).
Макс.

1
Усім, я використав відповідь, яку дав Сан 6 лютого. На інтеграцію до моєї розкадрування пішло 5 хвилин, і вона спрацювала чудово. Властивість Selector знаходиться під Інспектором підключень IB. Керування перетягуванням від UIButton до об’єкта ViewController, і методи з’являться. Торкніться потрібного методу, і ви майже зробили. Залишилось би лише очищення коду. Використовується btnXXXXX.hidden, щоб приховати та показати, щоб замінити barbuttonitem = nil. Але цей метод був легким і дуже чистим.
user589642

Відповіді:


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/…
Ерік Голдберг,

50

Іншим простим рішенням є

  1. Перетягніть стандартну кнопку UIB
  2. Встановіть стиль кнопки на замовлення та встановіть зображення для цієї кнопки
  3. Перетягніть його на панель UINavigationBar
  4. Встановити селектор

1
Мабуть, найпростіше рішення. Дякую!
Prine

1
Блискуче! Єдина примха - це не спрацює, якщо перетягнути кнопку прямо на панель навігації. Перед додаванням кнопки на панель навігації кнопку потрібно встановити як власну. Не знаю, чому, але це так. Отже, крок 1 - означає перетягування UIBatton кудись на ваш інтерфейс, крім панелі навігації.
Андрій Чийов,

1
важко бути простим та ефективним. Приємна відповідь
Add080bbA

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. Чому? Таким чином, щоб дія викликалася на ціль із правильним відправником. У наведеному вище коді аргументом відправника у повідомленні дії є екземпляр 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], а не використовувати прозоре зображення.
James Campbell

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];
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.