2012-02-29 11 views
6

私はUIBarButtonItemUIButtonをカスタムビューとして持っています。UIButtonをCustomViewとしたUIBarButtonItem - UIButtonからUIBarButtonItemにアクセスする方法は?

UIButtonは、addTarget:action:です。アクションで私はポップオーバーを提示する。私は現在、UIBarButtonItemから提示したいsender.frameUIButtonのフレーム)からプレゼンテーションしています。

UIBarButtonItemにはUIButtonからアクセスするにはどうすればよいですか?

答えて

9

あなたは、あなたがすることができ、UIBarButtonItemcustomView、またはカスタムビューの子としてあなたUIButtonを設定している場合ボタンが含まれているUIToolbarまたはUINavigationBarが見つかるまでビュー階層を上に移動し、カスタムビューがボタン(またはボタンの祖先)であるバーの項目を検索します。

これは私の完全にテストされていないコードです。ボタンを含む項目を取得するには[[self class] barButtonItemForView:myButton]に電話します。

+ (BOOL)ifBarButtonItem:(UIBarButtonItem *)item containsView:(UIView *)view storeItem:(UIBarButtonItem **)outItem { 
    UIView *customView = item.customView; 
    if (customView && [view isDescendantOfView:customView]) { 
     *outItem = item; 
     return YES; 
    } else { 
     return NO; 
    } 
} 

+ (BOOL)searchBarButtonItems:(NSArray *)items forView:(UIView *)view storeItem:(UIBarButtonItem **)outItem { 
    for (UIBarButtonItem *item in items) { 
     if ([self ifBarButtonItem:item containsView:view storeItem:outItem]) 
      return YES; 
    } 
    return NO; 
} 

+ (UIBarButtonItem *)barButtonItemForView:(UIView *)view { 
    id bar = view; 
    while (bar && !([bar isKindOfClass:[UIToolbar class]] || [bar isKindOfClass:[UINavigationBar class]])) { 
     bar = [bar superview]; 
    } 
    if (!bar) 
     return nil; 

    UIBarButtonItem *item = nil; 

    if ([bar isKindOfClass:[UIToolbar class]]) { 
     [self searchBarButtonItems:[bar items] forView:view storeItem:&item]; 
    } 

    else { 
     UINavigationItem *navItem = [bar topItem]; 
     if (!navItem) 
      return nil; 
     [self ifBarButtonItem:navItem.backBarButtonItem containsView:view storeItem:&item] 
     || [self ifBarButtonItem:navItem.leftBarButtonItem containsView:view storeItem:&item] 
     || [self ifBarButtonItem:navItem.rightBarButtonItem containsView:view storeItem:&item] 
     || ([navItem respondsToSelector:@selector(leftBarButtonItems)] 
      && [self searchBarButtonItems:[(id)navItem leftBarButtonItems] forView:view storeItem:&item]) 
     || ([navItem respondsToSelector:@selector(rightBarButtonItems)] 
      && [self searchBarButtonItems:[(id)navItem rightBarButtonItems] forView:view storeItem:&item]); 
    } 

    return item; 
} 
+0

あなたは男です!私はUIToolBarを使っているのでNavigationItemsをテストすることができませんでした。これはとてもうまくいきます!ありがとうございました! – scooter133

6

まず、なぜUIBarButtonItemにアクセスする必要がありますか?

カスタムビューでUIBarButtonItemを作成するには、次のようなカテゴリ拡張を作成することをお勧めします(この場合、カスタムビューはUIButtonです)。

//UIBarButtonItem+Extension.h  
+ (UIBarButtonItem*)barItemWithImage:(UIImage*)image title:(NSString*)title target:(id)target action:(SEL)action; 

//UIBarButtonItem+Extension.m  
+ (UIBarButtonItem*)barItemWithImage:(UIImage*)image title:(NSString*)title target:(id)target action:(SEL)action 
{ 
    UIButton *button = [UIButton buttonWithType:UIButtonTypeCustom]; 
    button.frame = CGRectMake(0.0, 0.0, image.size.width, image.size.height); 
    button.titleLabel.textAlignment = UITextAlignmentCenter; 

    [button setBackgroundImage:image forState:UIControlStateNormal]; 
    [button setTitle:title forState:UIControlStateNormal]; 
    [button addTarget:target action:action forControlEvents:UIControlEventTouchUpInside]; 

    UIBarButtonItem* barButtonItem = [[UIBarButtonItem alloc] initWithCustomView:button]; 

    return [barButtonItem autorelease];  
} 

このような用途それ(第UIBarButtonItem+Extension.hをインポート):セレクタは、それがバーボタン項目ことを使用するクラス(ターゲット)内に実装される方法だ

UIBarButtonItem* backBarButtonItem = [UIBarButtonItem barItemWithImage:[UIImage imageNamed:@"YoutImageName"] title:@"YourTitle" target:self action:@selector(doSomething:)]; 

今、あなたは以下の可能性がdoSomething:セレクタ内側:

- (void)doSomething:(id)sender 

    UIButton* senderButton = (UIButton*)sender;  
    [popover presentPopoverFromRect:senderButton.bounds inView:senderButton...]; 
} 

カテゴリこの場合には、それはコードを複製しないように便利です。それが役に立てば幸い。

P.S.私はARCを使用していませんが、同じ考慮事項を適用することもできます。

編集:

バーボタンアイテムにアクセスするための簡単な解決策は、以下のようになります。UIButton

  • が、その中にタイプUIBarButtonItem(弱いもののプロパティを作成します

    1. サブクラス保持期間を避けるため)
    2. 作成時にUIButtonのバーボタン項目を注入します。

    多分それはうまくいくかもしれませんが、私は最初のものを好むでしょう。

  • +0

    を私は何かを持っていますあなたのコードと同じように、UIBarButtonItemのサブクラスはボタンのルック・アンド・フィールをしましたが、かなりカスタムです。問題は '[popover presentPopoverFromRect:senderButton.bounds inView:senderButton ...];です。 UBarButtonItemからポップオーバーを提示すると、そのすべてとUIBarButtonItemに常にアンカーが削除されます。 – scooter133

    0

    UIButtonが必要かどうかは不明です。あなたがやっていることがアクションをディスパッチしたり、ボタンを画像でカスタマイズしたりするのであれば、UIBarButtonItemで十分です。

    プレゼンテーションを達成するために、UIButtonからフレームを取得する場合は、UIBarButtonItemの位置を単純に見積もることをお勧めします。これは特に難しいことではありません。特に、UINavigationItemleftBarButtonItemまたはrightBarButtonItemのいずれかの場合です。

    私は一般的にキス(Keep It Simple、Stupid!)の経験則です。 Appleもこれを行います...あなたがSpringboardからアプリを起動すると、アプリのアイコンからではなく、画面の中心から常に展開されます。

    ちょっとした提案です。

    EDIT

    OK、私はちょうど読んUIPopoverController reference(私は1つを使用したことがありません)。あなたが望むものはpresentPopoverFromBarButtonItem:permittedArrowDirections:animated:で、最初のパラメータとしてBBIを渡すと思います。メソッドが存在する理由は、あなたの問題を解決することです.BBIにはNSViewのサブクラスではないためフレームがありません。 Appleはあなたがこの種のことをしたいと知っており、この方法を提供しています。また、この方法を使うと、オートローテーションもうまくいくと思います。私はこれについて間違っているかもしれない、それを撃つ。

    カスタマイズされたレイアウトに関しては、UIViewでそれを複製し、そのカスタムBBIカスタムを作成すると、よりうまくいくと思います。これはもちろんあなた次第です。

    どちらの方法でも、IBOとIBOutletをNIBに接続するか、コードでコードを作成するときに参照を保存することで、BBIへの参照を取得できます。それから私は上記のpopoverメソッドにその参照を渡します。私はこれがあなたのために働くかもしれないと思います。

    MOAR

    BBIは自分のクラスのメンバーである - それは上の強い参照プロパティとIVAR、おそらくあなたのNIBへのIBOutletとしてリンクアップ。次に、クラス内の任意のメソッドからアクセスできます。

    例:(私は右のポップオーバーコントローラのメモリ管理を持っていることを確認していない)

    @interface MyViewController : UIViewController { 
        UIBarButtonItem *item; 
    } 
    
    @property (nonatomic, retain) UIBarButtonItem *item; 
    
    @end 
    
    
    
    @implementation MyViewController 
    
    @synthesize item; 
    
    -(void)viewDidLoad { 
        // assuming item isn't in your NIB 
        item = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemPlus target:self action:@selector(doit)]; 
        self.navigationItem.rightBarButtonItem = item; 
    } 
    
    -(void)doit { 
        UIPopoverController *popover = [[[UIPopoverController alloc] initWithContentViewController:yourViewController] autorelease]; 
        [popover presentPopoverFromBarButtonItem:self.item permittedArrowDirections:UIPopoverArrowDirectionAny animated:YES]; 
        // or in the line above, replace self.item with self.navigationItem.rightBarButtonItem 
    } 
    
    @end 
    
    +0

    実際の問題は、UIButtonのアクションから提示されるPopoverです。私がスクリーンを回転させると、ポップオーバーはUIBarButtonItemにアンカーされず、UIButtonであるアクションの送信者のフレームに固定されます。私は私のUIToolBarがCustomであるのでUIButtonが必要でした。ボタンは底辺の84x48、3つのボタン、フレックススペース、4つのボタンです。UButtonを使用すると、BartButtonItemに84x48の特定の位置にカスタムグラフィックとラベルを持たせることができます。 – scooter133

    +0

    BarButtonItemsから提示されるPopoversには位置決めの問題がないため、UIButtonでsender.superViewを実行してUIBarButtonItemを取得できると考えました。代わりに私はUIToolBarを取得します。私はタグの位置を持っています、UIBoolButtonItemのUIToolBarをただトラバースできますか? – scooter133

    +0

    hrms .... hang one – QED

    0

    のは、次のようUIBarButtonItem info_ButtonにUIButton aButtonを追加したとしましょう:

    //Add a button on top of the UIBarButtonItem info_button 
    UIButton *aButton = [UIButton buttonWithType:UIButtonTypeInfoLight]; 
    [aButton addTarget:self action:@selector(showInfo:) forControlEvents:UIControlEventTouchUpInside]; 
    info_Button.customView = aButton; 
    

    を今、SHOWINFO、presentPopoverFromBarButtonItemに:(代わりにpresentPopoverFromBarButtonItemの:送信者)info_Button、これはUIBarButtonItem info_buttonを渡します作品の上にポップを作るために:

    - (IBAction)showInfo:(id)sender 
    { 
        [self.flipsidePopoverController presentPopoverFromBarButtonItem:info_Button permittedArrowDirections:UIPopoverArrowDirectionAny animated:YES]; 
    
    } 
    
    0
    // get the UIBarButtonItem from the UIButton that is passed in sender 
    UIToolbar *toolbar = (id)[sender superview]; 
    UIBarButtonItem *ourButtonItem = [toolbar items][2];//pick the right index 
    [parkingPopOver_ presentPopoverFromBarButtonItem:ourButtonItem permittedArrowDirections:UIPopoverArrowDirectionAny animated:YES]; 
    
    関連する問題