UIBarButtonItem dengan gambar khusus dan tanpa batas

89

Saya ingin membuat UIBarButtonItem dengan gambar khusus, tetapi saya tidak ingin bingkai yang ditambahkan iPhone, karena Gambar saya memiliki bingkai khusus.

Ini sama dengan tombol kembali tetapi tombol maju.

Aplikasi ini untuk proyek inHouse, jadi saya tidak peduli apakah Apple menolak atau menyetujuinya atau menyukainya :-)

Jika saya menggunakan properti initWithCustomView: v dari UIBarButtonItem, saya bisa melakukannya:

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

Ini berfungsi, tetapi jika saya harus mengulangi proses ini dalam 10 tampilan, ini tidak KERING.

Saya kira saya harus subclass, tapi apa?

  • NSView?
  • UIBarButtonItem?

Terima kasih,

salam,

Mongeta
sumber
3
Terima kasih telah membagikan kode Anda, hanya itu yang saya butuhkan :).
Max
1
Semuanya, saya menggunakan jawaban yang diberikan oleh San pada 6 Februari. Butuh waktu 5 menit untuk mengintegrasikannya ke dalam Storyboard saya, dan itu bekerja dengan sempurna. Properti Selector berada di bawah Connections Inspector of IB. Kontrol seret dari UIButton ke objek ViewController dan metode akan muncul. Ketuk metode yang Anda inginkan dan Anda cukup banyak selesai. Satu-satunya yang tersisa adalah pembersihan kode. Digunakan btnXXXXX.hidden untuk menyembunyikan dan menampilkan untuk mengganti barbuttonitem = nil. Tetapi metode ini mudah dan sangat bersih.
pengguna589642

Jawaban:

44

Anda dapat menambahkan metode ke UIBarButtonItem tanpa mensubclassinya menggunakan kategori khusus:

@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

Jadi di mana pun dalam kode Anda, Anda dapat membuat item batang yang memanggil metode ini (asalkan Anda menyertakan header dengan deklarasinya).

PS Anda tidak perlu menggunakan 'v' UIView karena Anda dapat membuat UIBarButtonItemdengan tombol sebagai tampilan kustom secara langsung.
PPS Anda juga membutuhkan [rilis maju] dalam kode Anda.

Vladimir
sumber
Kategori khusus: Saya harus membuat file header dengan deklarasi tersebut, dan file implementasi, di mana saya meletakkan kode yang Anda maksud? terima kasih
mongeta
Ini bekerja sangat banyak tetapi saya tidak dapat menulis pemilih Saya tidak ingin menulis pemilih pada kategori bagaimana saya bisa menulisnya di kelas saya
Nilesh Tupe
@NileshTupe apa maksudmu? Anda meneruskan metode pemilih dan target - jadi target dapat berupa objek apa pun yang Anda inginkan
Vladimir
2
BTW- Saya menambahkan ini ke repo open source kecil saya untuk kategori kenyamanan UIKit. Terima kasih @Vladimir atas inspirasinya. (perhatikan semua barang saya berbasis ARC) github.com/egold/UIKitConvenience/blob/master/UIKitConvenience/…
Eric Goldberg
50

Solusi sederhana lainnya adalah

  1. Tarik UIButton standar
  2. Atur gaya tombol menjadi kustom dan atur gambar Anda untuk tombol itu
  3. Seret ke UINavigationBar
  4. Setel Pemilih
san
sumber
1
Mungkin solusi termudah. Terima kasih!
Prine
1
Cemerlang! Satu-satunya kekhasan - tidak akan berhasil jika Anda menyeret tombol langsung ke bilah navigasi. Tombol harus disetel ke kustom sebelum ditambahkan ke bilah navigasi. Tidak yakin mengapa, tapi begitulah adanya. Jadi langkah # 1 - berarti seret UIBatton ke suatu tempat di UI Anda selain bilah navigasi.
Andrei Tchijov
1
sulit untuk menjadi sederhana dan efektif. Jawaban bagus
Add080bbA
37

Saya menemukan cara ini mudah. Itu disarankan di atas. "random.png" harus ada dalam proyek. Cukup seret dan lepas gambar apa pun.

 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;
m-farhan
sumber
6

Alternatifnya adalah subclass UIBarButtonItem. Mengapa? Sehingga tindakan tersebut dipanggil pada target dengan pengirim yang benar. Dalam kode di atas, argumen pengirim dalam pesan tindakan adalah instance UIButton, bukan instance UIBarButtonItem. Ini penting, misalnya, jika Anda ingin menampilkan UIPopoverController dari item tombol bar. Dengan membuat subclass UIBarButtonItem, Anda dapat menambahkan ivar yang mempertahankan target asli, memungkinkan instance subclass kami untuk mencegat, mengubah, dan meneruskan pesan tindakan dengan pengirim yang tepat.

Jadi, CCFBarButtonItem.h:

#import <uIKit/UIBarButtonItem.h>

@interface CCFBarButtonItem : UIBarButtonItem
{
@protected
    id _originalTarget;
}
- (id)initWithImage:(UIImage *)image target:(id)target action:(SEL)action;
@end

dan 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
FluffulousChimp
sumber
5
UIBarButtonItem *menuItem = [[UIBarButtonItem alloc] initWithImage: [UIImage imageNamed:@"icon-menu.png"]
                                                                    style:UIBarButtonItemStylePlain
                                                                   target:self
                                                                   action:@selector(showMenu)];
alexmorhun
sumber
3

Ini juga dapat dilakukan secara terprogram (tentu saja):

Pertama, buat tampilan kustom. Tampilan kustom ini dapat berisi gambar, tombol, atau apa pun yang Anda inginkan. Tampilan kustom dapat dibuat secara terprogram atau di 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];

Selanjutnya, buat UIBarButtonItem dan inisialisasi dengan tampilan kustom.

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

Sekarang, tambahkan saja UIBarButton kustom ke leftBarButtonItem:

self.navigationItem.leftBarButtonItem = customBarButtonItem;
abriggs
sumber
1

Ok kategori itu berfungsi dengan sangat baik karena tidak ada masalah dengan 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
Raegtime
sumber
1

Lihat solusi sederhana ini.

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

Di sini 1x1.png adalah gambar png transparan 1 piksel yang dapat Anda unduh dari tautan di bawah ini

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

Fremy Jose
sumber
Anda bisa menggunakan [UIImage new] daripada menggunakan gambar transparan.
James Campbell
0

Satu solusi lain, anggap lebih sederhana jika membuat tombol secara terprogram:

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];
Mikhail
sumber