사용자 정의 이미지가 있고 테두리가없는 UIBarButtonItem


89

사용자 지정 이미지로 UIBarButtonItem을 만들고 싶지만 내 이미지에 특수 테두리가 있으므로 iPhone이 추가하는 테두리를 원하지 않습니다.

뒤로 버튼과 동일하지만 앞으로 버튼입니다.

이 앱은 사내 프로젝트 용이므로 Apple이 거부하거나 승인하거나 좋아하든 상관 없습니다 :-)

UIBarButtonItem의 initWithCustomView : v 속성을 사용하면 다음과 같이 할 수 있습니다.

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 개의 뷰에서이 과정을 반복해야한다면 DRY가 아닙니다.

나는 하위 클래스를해야한다고 생각하지만 무엇?

  • NSView?
  • UIBarButtonItem?

감사,

문안 인사,


3
코드를 공유해 주셔서 감사합니다. 그게 제가 필요한 전부입니다. :).
Max

1
여러분, 저는 2 월 6 일에 San이 제공 한 답변을 사용했습니다. 내 스토리 보드에 통합하는 데 5 분이 모두 걸렸고 완벽하게 작동했습니다. Selector 속성은 IB의 Connections Inspector 아래에 있습니다. 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

따라서 코드의 어느 곳에서나이 메서드를 호출하는 막대 항목을 만들 수 있습니다 (선언과 함께 헤더를 포함하는 경우).

추신 : 'v'UIView를 사용할 필요는 없습니다 UIBarButtonItem. 버튼으로 직접 커스텀 뷰로 만들 수 있습니다.
PPS 코드에 [forward release]도 필요합니다.


사용자 지정 범주 : 해당 선언으로 헤더 파일을 만들어야하고, 참조하는 코드를 넣은 구현 파일을 만들어야합니다. 감사
mongeta

그것의 작업은 많이 고맙지 만 나는 선택자를 쓸 수 없습니다 나는 카테고리에 선택자를 작성하고 싶지 않습니다 어떻게 내 수업에 그것을 쓸 수
있습니까

@NileshTupe 무슨 뜻이야? 당신은 선택 방법 통과 하고 대상이 될 수 있도록 당신이 원하는 객체간에 - 목표
블라디미르

2
BTW- 나는 이것을 UIKit 편의 카테고리에 대한 내 작은 오픈 소스 저장소에 추가했습니다. 영감을 주신 @Vladimir에게 감사드립니다. (내 물건 ARC 기반의 모든주의) github.com/egold/UIKitConvenience/blob/master/UIKitConvenience/...
에릭 골드버그

50

또 다른 간단한 해결책은

  1. 표준 UIButton 드래그
  2. 버튼의 스타일을 사용자 지정으로 설정하고 해당 버튼의 이미지를 설정합니다.
  3. UINavigationBar로 드래그하세요.
  4. 선택기 설정

1
아마도 가장 쉬운 해결책 일 것입니다. 감사!
Prine 2012

1
훌륭한! 유일한 단점은 버튼을 탐색 모음으로 바로 드래그하면 작동하지 않습니다. 버튼을 탐색 모음에 추가하기 전에 사용자 정의로 설정해야합니다. 이유는 확실하지 않지만 이것이 방법입니다. 따라서 # 1 단계-탐색 모음이 아닌 UI의 어딘가에 UIBatton을 드래그하는 것을 의미합니다.
Andrei Tchijov 2013-08-29

1
간단하고 효과적이기는 어렵습니다. 좋은 답변
Add080bbA 2014-12-11

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을 하위 클래스로 만드는 것입니다. 왜? 따라서 올바른 보낸 사람을 사용하여 대상에서 작업이 호출됩니다. 위 코드에서 작업 메시지의 sender 인수는 UIBarButtonItem 인스턴스가 아니라 UIButton 인스턴스입니다. 예를 들어, 막대 버튼 항목에서 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];
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.