UIBarButtonItem พร้อมรูปภาพที่กำหนดเองและไม่มีเส้นขอบ


89

ฉันต้องการสร้าง 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?

ขอบคุณ

ความนับถือ,


3
ขอบคุณสำหรับการแบ่งปันรหัสของคุณนั่นคือทั้งหมดที่ฉันต้องการ :)
สูงสุด

1
ทุกคนฉันใช้คำตอบที่ซานให้ไว้เมื่อวันที่ 6 กุมภาพันธ์ใช้เวลาทั้งหมด 5 นาทีในการรวมเข้ากับ Storyboard ของฉันและมันก็ทำงานได้อย่างสมบูรณ์แบบ คุณสมบัติ Selector อยู่ภายใต้ Connections Inspector ของ IB ควบคุมการลากจาก UIButton ไปยังวัตถุ ViewController และวิธีการต่างๆจะปรากฏขึ้น แตะวิธีที่คุณต้องการและคุณทำได้สำเร็จ สิ่งเดียวที่เหลือคือการล้างโค้ด ใช้ btnXXXXX ซ่อนเพื่อซ่อนและเลิกซ่อนเพื่อแทนที่ 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

ดังนั้นที่ใดก็ได้ในโค้ดของคุณคุณสามารถสร้างรายการบาร์ที่เรียกใช้เมธอดนี้ได้ (โดยที่คุณรวมส่วนหัวพร้อมกับการประกาศ)

ปล. คุณไม่จำเป็นต้องใช้ UIView 'v' เนื่องจากคุณสามารถสร้างUIBarButtonItemด้วยปุ่มเป็นมุมมองที่กำหนดเองได้โดยตรง
PPS คุณต้องมี [forward release] ในรหัสของคุณด้วย


หมวดหมู่ที่กำหนดเอง: ฉันต้องสร้างไฟล์ส่วนหัวด้วยการประกาศเหล่านั้นและไฟล์การนำไปใช้ที่ฉันใส่รหัสที่คุณอ้างถึง? ขอบคุณ
mongeta

มันใช้งานได้ดีมาก แต่ฉันไม่สามารถเขียนตัวเลือกได้ฉันไม่ต้องการเขียนตัวเลือกในหมวดหมู่ฉันจะเขียนมันในชั้นเรียนของฉันได้อย่างไร
Nilesh Tupe

@NileshTupe คุณหมายถึงอะไร? คุณผ่านวิธีการเลือกและเป้าหมายดังนั้นเป้าหมายสามารถเป็นวัตถุอะไรก็ได้ที่คุณต้องการ
Vladimir

2
BTW- ฉันเพิ่มสิ่งนี้ลงใน repo โอเพ่นซอร์สเล็ก ๆ ของฉันสำหรับหมวดหมู่ความสะดวกสบายของ UIKit ขอบคุณ @Vladimir สำหรับแรงบันดาลใจ (สังเกตทุกอย่างของฉันใช้ ARC) github.com/egold/UIKitConvenience/blob/master/UIKitConvenience/…
Eric Goldberg

50

อีกวิธีง่ายๆคือ

  1. ลาก UIButton มาตรฐาน
  2. ตั้งค่ารูปแบบของปุ่มเป็นแบบกำหนดเองและตั้งค่ารูปภาพของคุณสำหรับปุ่มนั้น
  3. ลากไปยัง UINavigationBar
  4. ตั้งค่าตัวเลือก

1
น่าจะเป็นทางออกที่ง่ายที่สุด ขอบคุณ!
รีน

1
ยอดเยี่ยม! มุมแหลมเพียงอย่างเดียว - จะใช้ไม่ได้หากคุณลากปุ่มตรงไปที่แถบนำทาง ต้องตั้งค่าปุ่มเป็นแบบกำหนดเองก่อนที่จะเพิ่มลงในแถบนำทาง ไม่แน่ใจว่าทำไม แต่นี่คือวิธีการ ดังนั้นขั้นตอนที่ # 1 - หมายถึงลาก UIBatton ไปที่ใดที่หนึ่งบน UI ของคุณนอกเหนือจากแถบนำทาง
Andrei Tchijov

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 ที่กำหนดเองทางด้านซ้ายBarButtonItem:

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 นี่คือภาพ png โปร่งใส 1 พิกเซลซึ่งคุณสามารถดาวน์โหลดได้จากลิงค์ด้านล่าง

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


คุณสามารถใช้ [UIImage ใหม่] แทนการใช้ภาพโปร่งใส
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];
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.