UIBarButtonItem với hình ảnh tùy chỉnh và không có đường viền


89

Tôi muốn tạo UIBarButtonItem với hình ảnh tùy chỉnh, nhưng tôi không muốn đường viền mà iPhone thêm vào, vì Hình ảnh của tôi có đường viền đặc biệt.

Nó giống như nút quay lại nhưng là nút chuyển tiếp.

Ứng dụng này dành cho một dự án inHouse, vì vậy tôi không quan tâm liệu Apple có từ chối hay phê duyệt hay thích nó hay không :-)

Nếu tôi sử dụng thuộc tính initWithCustomView: v của UIBarButtonItem, tôi có thể làm điều đó:

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

Điều này hoạt động, nhưng nếu tôi phải lặp lại quá trình này trong 10 lần xem, thì đây không phải là KHÔ.

Tôi cho rằng tôi phải phân lớp, nhưng sao?

  • NSView?
  • UIBarButtonItem?

cảm ơn,

Trân trọng,


3
Cảm ơn vì đã chia sẻ mã của bạn, đó là tất cả những gì tôi cần :).
Tối đa

1
Mọi người, tôi đã sử dụng câu trả lời do San cung cấp vào ngày 6 tháng 2. Mất tất cả 5 phút để tích hợp vào Bảng phân cảnh của tôi và nó hoạt động hoàn hảo. Thuộc tính Bộ chọn nằm trong Thanh tra kết nối của IB. Điều khiển kéo từ UIButton đến đối tượng ViewController và các phương thức sẽ bật lên. Nhấn vào phương pháp bạn muốn và bạn đã hoàn thành khá nhiều việc. Điều duy nhất còn lại sẽ là một số dọn dẹp mã. Đã sử dụng btnXXXXX.hiised để ẩn và hiện để thay thế barbuttonitem = nil. Nhưng phương pháp này rất dễ dàng và rất sạch sẽ.
user589642

Câu trả lời:


44

Bạn có thể thêm một phương thức vào UIBarButtonItem mà không cần phân lớp nó bằng cách sử dụng danh mục tùy chỉnh:

@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

Vì vậy, bất cứ nơi nào trong mã của bạn, bạn có thể tạo thanh mục gọi phương thức này (miễn là bạn bao gồm tiêu đề với khai báo của nó).

PS Bạn không cần sử dụng 'v' UIView vì bạn có thể tạo UIBarButtonItemtrực tiếp bằng một nút dưới dạng chế độ xem tùy chỉnh.
PPS Bạn cũng cần [bản phát hành chuyển tiếp] trong mã của mình.


Danh mục tùy chỉnh: Tôi phải tạo tệp tiêu đề với các khai báo đó và tệp triển khai, nơi tôi đặt mã mà bạn đang tham khảo? cảm ơn
mongeta

Thanx công việc của mình rất nhiều nhưng tôi không thể viết selector i dont muốn viết selector vào loại làm thế nào tôi có thể viết nó vào lớp học của tôi
Nilesh Tupe

@NileshTupe ý bạn là gì? Bạn vượt qua phương pháp chọn mục tiêu - vì vậy mục tiêu có thể được bất cứ điều gì bạn muốn đối tượng
Vladimir

2
BTW- Tôi đã thêm cái này vào kho mã nguồn mở nhỏ của mình cho các danh mục tiện lợi UIKit. Cảm ơn @Vladimir về nguồn cảm hứng. (lưu ý tất cả nội dung của tôi đều dựa trên ARC) github.com/egold/UIKitConvenience/blob/master/UIKitConvenience/…
Eric Goldberg

50

Một giải pháp đơn giản khác là

  1. Kéo một UIButton chuẩn
  2. Đặt kiểu của nút thành tùy chỉnh và đặt hình ảnh của bạn cho nút đó
  3. Kéo nó vào UINavigationBar
  4. Đặt bộ chọn

Có lẽ là giải pháp dễ dàng nhất. Cảm ơn!
Prine

1
Xuất sắc! Điều kỳ quặc duy nhất - nó sẽ không hoạt động nếu bạn kéo nút thẳng đến thanh điều hướng. Nút phải được đặt thành tùy chỉnh trước khi được thêm vào thanh điều hướng. Không chắc tại sao, nhưng nó là như thế này. Vì vậy, bước # 1 - có nghĩa là kéo UIBatton vào một nơi nào đó trên giao diện người dùng của bạn ngoài thanh điều hướng.
Andrei Tchijov

khó mà đơn giản và hiệu quả. Nice câu trả lời
Add080bbA

37

Tôi thấy nó theo cách này dễ dàng. Nó có đường ở trên cùng. "random.png" phải ở trong dự án. Chỉ cần kéo và thả bất kỳ hình ảnh nào.

 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

Một thay thế là cho lớp con UIBarButtonItem. Tại sao? Để hành động được gọi trên đích với đúng người gửi. Trong đoạn mã trên, đối số người gửi trong thông báo hành động là cá thể UIButton, không phải cá thể UIBarButtonItem. Điều này sẽ quan trọng, ví dụ, nếu bạn muốn trình bày một UIPopoverController từ mục nút thanh. Bằng cách phân lớp con UIBarButtonItem, bạn có thể thêm một ivar giữ lại mục tiêu ban đầu, cho phép các cá thể lớp con của chúng tôi chặn, sửa đổi và chuyển tiếp thông báo hành động với người gửi thích hợp.

Vì vậy, CCFBarButtonItem.h:

#import <uIKit/UIBarButtonItem.h>

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

và 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

Điều này cũng có thể được thực hiện theo chương trình (tất nhiên):

Đầu tiên, tạo một chế độ xem tùy chỉnh. Chế độ xem tùy chỉnh này có thể chứa hình ảnh, nút hoặc bất kỳ thứ gì khác mà bạn muốn. Chế độ xem tùy chỉnh có thể được thực hiện theo chương trình hoặc trong 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];

Tiếp theo, tạo UIBarButtonItem và khởi tạo nó với dạng xem tùy chỉnh.

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

Bây giờ, chỉ cần thêm UIBarButton tùy chỉnh vào leftBarButtonItem:

self.navigationItem.leftBarButtonItem = customBarButtonItem;

1

Ok danh mục đó hoạt động rất tốt vì không có vấn đề gì với 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

Kiểm tra giải pháp đơn giản này.

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

Đây 1x1.png là một hình ảnh png trong suốt 1 pixel mà bạn có thể tải xuống từ liên kết bên dưới

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


Bạn chỉ có thể sử dụng [UIImage new] thay vì sử dụng hình ảnh trong suốt.
James Campbell

0

Một giải pháp khác, hãy nghĩ rằng nó đơn giản hơn trong trường hợp tạo nút theo chương trình:

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];
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.