カスタム画像と境界線のないUIBarButtonItem


89

カスタム画像でUIBarButtonItemを作成したいのですが、画像に特別な境界線があるため、iPhoneが追加する境界線は必要ありません。

戻るボタンと同じですが、進むボタンです。

このアプリはinHouseプロジェクト用なので、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
あなたのコードを共有してくれてありがとう、それは私が必要なすべてです:)。
最大

1
皆さん、2月6日にSanから提供された回答を使用しました。ストーリーボードに統合するのに5分かかりましたが、それは完全に機能しました。Selectorプロパティは、IBの接続インスペクターの下にあります。UIButtonからViewControllerオブジェクトへのドラッグを制御すると、メソッドがポップアップします。希望する方法をタップすると、ほとんど完了です。残っているのはコードのクリーンアップだけです。btnXXXXX.hiddenを使用して非表示にし、再表示してbarbuttonitem = nilを置き換えました。しかし、この方法は簡単でとてもきれいでした。
user589642 2012

回答:


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 UIBarButtonItemボタンで直接カスタムビューとして作成できるため、「v」UIViewを使用する必要はありません。
PPSまた、コードに[フォワードリリース]が必要です。


カスタムカテゴリ:これらの宣言を含むヘッダーファイルと、参照しているコードを配置する実装ファイルを作成する必要がありますか?感謝
mongeta 2010

その作業はたくさんありますが、セレクターを書くことができません。カテゴリーにセレクターを書きたくありません。クラスにどのように書けばよいですか
Nilesh Tupe '21

@NileshTupeどういう意味ですか?セレクターメソッドターゲットを渡すと、ターゲットを任意のオブジェクトにできます
Vladimir

2
ところで、UIKitのコンビニエンスカテゴリ用に、これを小さなオープンソースリポジトリに追加しました。インスピレーションを与えてくれた@Vladimirに感謝します。(ノートでは、すべて私のものは、ARCベースである) github.com/egold/UIKitConvenience/blob/master/UIKitConvenience/...
エリック・ゴールドバーグ

50

別の簡単な解決策は

  1. 標準のUIButtonをドラッグします
  2. ボタンのスタイルをカスタムに設定し、そのボタンの画像を設定します
  3. それをUINavigationBarにドラッグします
  4. セットセレクター

おそらく最も簡単なソリューションです。ありがとう!
Prine

1
鮮やかさ!唯一の癖-ボタンを直接ナビゲーションバーにドラッグしても機能しません。ボタンは、ナビゲーションバーに追加する前にカスタムに設定する必要があります。理由は定かではありませんが、これがその方法です。つまり、ステップ#1-UIBattonをナビゲーションバー以外のUIのどこかにドラッグします。
Andrei Tchijov 2013

シンプルで効果的であることは難しいです。いい答え
Add080bbA 2014

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]を使用することもできます。
ジェームズキャンベル

0

もう1つの解決策は、プログラムでボタンを作成する場合の方が簡単だと考えます。

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.