UIBarButtonItemを表示/非表示にするにはどうすればよいですか?


251

いくつかのボタンを備えたIBのツールバーを作成しました。メインウィンドウのデータの状態に応じて、いずれかのボタンの表示/非表示を切り替えたいのですが。

UIBarButtonItem 非表示のプロパティはなく、非表示にするためにこれまでに見つけた例には、ナビゲーションバーのボタンをnilに設定することが含まれます。ちなみに、ボタンをIBOutletに接続している場合、それをnilに設定すると、どのようにして元に戻すことができるかわかりません)。


私は単にそれを無効にし、ボタンの機能が利用できないことを示すアクセシビリティラベルを追加しました。
Daniel Springer、

回答:


263

ボタンを強力なアウトレットに保存し(myButtonこれをと呼びましょう)、これを実行して追加/削除します。

// Get the reference to the current toolbar buttons
NSMutableArray *toolbarButtons = [self.toolbarItems mutableCopy];

// This is how you remove the button from the toolbar and animate it
[toolbarButtons removeObject:self.myButton];
[self setToolbarItems:toolbarButtons animated:YES];

// This is how you add the button to the toolbar and animate it
if (![toolbarButtons containsObject:self.myButton]) {
    // The following line adds the object to the end of the array.  
    // If you want to add the button somewhere else, use the `insertObject:atIndex:` 
    // method instead of the `addObject` method.
    [toolbarButtons addObject:self.myButton];
    [self setToolbarItems:toolbarButtons animated:YES];
}

アウトレットに保存されているため、ツールバーにない場合でも参照できます。


73
これをナビゲーションコントローラーの右ボタンで機能させるために、toolBarItemsとsetToolBarItemsの代わりに、self.navigationItem.rightBarButtonItemsと[self.navigationItem setRightBarButtonItems <prams>]を使用しました。
MindSpiker

@MindSpiker:はい、同じ手法がナビゲーションバーのボタンにも機能します。
lnafziger

1
deallocでmyButtonをnilする必要がありますか?
Van Du Tran 2013年

48
または、Appleが.hiddenプロパティを追加しただけかもしれません。-_-
GeneCode、

217

私はこの答えがこの質問に遅れていることを知っています。ただし、他の誰かが同様の状況に直面している場合、それは役立つかもしれません。

iOS 7では、バーボタンアイテムを非表示にするには、次の2つの方法を使用できます。

  • 使用SetTitleTextAttributes:-これは、「完了」、「保存」などのバーボタンアイテムではうまく機能します。ただし、テキストではないため、追加、ゴミ箱記号などのアイテムでは機能しません。
  • 使用TintColor:-「deleteButton」と呼ばれるバーボタンアイテムがある場合:-

ボタンを非表示にするために、次のコードを使用しました:-

[self.deleteButton setEnabled:NO]; 
[self.deleteButton setTintColor: [UIColor clearColor]];

ボタンを再度表示するには、次のコードを使用しました:

[self.deleteButton setEnabled:YES];
[self.deleteButton setTintColor:nil];

[self.navigationItem.rightBarButtonItem setEnabled:NO]; [self.navigationItem.rightBarButtonItem setTintColor:[UIColor clearColor]];
レオン

3
Swiftの場合:deleteButton.enabled = false; deleteButton.tintColor = UIColor.clearColor()無効にして非表示にし、deleteButton.enabled = true; deleteButton.tintColor = nil通常どおり再度有効にして表示します。
Unixmonkey 2015

1
この方法では、UIBarButtonをそのクラス内に表示するかどうかのロジックを配置できるのが気に入っています。ボタンが1つだけの場合に機能する理由はすぐにはわかりません。この方法でボタンを非表示にしても、スペースを占有するため、複数のボタンがある場合は空のギャップが生じる可能性があります。
SimplGy 2016年

あなたの最初のアプローチは私にとって完璧でした。に設定UIColor.clearUIControlState.disabled、でボタンを表示/非表示にできますsetEnabled。もちろん、あなたが述べたように、これはテキストボタンに対してのみ機能します。
fl034 2018

大きな画像に表示されるまで(おそらくアクセシビリティのため)、長押しすると、isEnabledがfalseに設定されていても機能します。
ダニエルスプリンガー

67

ここに簡単なアプローチがあります:

hide:  barbuttonItem.width = 0.01;
show:  barbuttonItem.width = 0; //(0 defaults to normal button width, which is the width of the text)

私は網膜のiPadでそれを実行したところ、.01は十分に小さく、表示されません。


13
すべてのソリューションの中で、これは迅速で、汚く、効果的でした。また、barbuttItem.enabled = NO;も追加しました。ボタンを十分にたたくと、ボタンが発動する可能性があるためです。
Stickley 2012

1
うまくいきません。「+」画像のある[追加]ボタンを使用しているためだと思いましたが、代わりに「新規」というテキストを使用してカスタムボタンを試しても、消えません。有効化が変更され、コードが実行されていることがわかります。何か案は?このボタンは、ストーリーボードで作成され、私が代わりに、プログラムボタンに変更したくないので、セグエを持っていることに注意してください
ルバーブ

19
ナビゲーションコントローラーのツールバーでは機能しないようですが、他のツールバーでは機能します。
Drew Rosenberg

3
それはそれを隠しますが、それでもタップに反応します。私にとっては、それは目に見えないボタンのように機能します。
ティビダボ2013

self.window?.tintColor = APP_PRIMARY_COLORappdelegateでこの行を使用してグローバルティントカラーを設定した場合、これは機能しません
Mehul Thakkar

60

ボタンの幅を変更したり、バーから削除したりせずに、ボタンを非表示にすることができます。スタイルをプレーンに設定し、タイトルを削除してボタンを無効にすると、スタイルは非表示になります。元に戻すには、変更を元に戻します。

-(void)toggleBarButton:(bool)show
{
    if (show) {
        btn.style = UIBarButtonItemStyleBordered;
        btn.enabled = true;
        btn.title = @"MyTitle";
    } else {
        btn.style = UIBarButtonItemStylePlain;
        btn.enabled = false;
        btn.title = nil;
    }
}

2
これは、btn.title = nilを設定するだけでうまくいきました。私も...念のため、NO =有効に設定しています
豚肉を「N」バニー

3
iOS7では、buttonItem.titleをnilに設定しても機能しませんでした。ボタンを元に戻すと、ボタンは再表示されませんでした。ただし、機能したのはbuttonItem.title = @ ""を設定することでした。
Mark Knopper 2013年

42

ナビゲーションバーを探していましたが、以下が私の解決策です。

navBar.topItem.rightBarButtonItem = nil;

ここで「navBar」は、XIBのビューにあるNavigationBarへのIBOutletです。ここでは、ボタンを非表示にするか、何らかの条件に基づいて表示したいと考えていました。したがって、「If」で条件をテストし、trueの場合、ターゲットビューのviewDidLoadメソッドでボタンをnilに設定しています。

これは問題に正確に関連しているわけではありませんが、NavigationBarのボタンを非表示にする場合は、同様のケースになります。


後でrightBarButtonItem再度設定する場合は、ボタン項目が強力な IBOutletに格納されていることを確認して、ナビゲーションバーからボタンを離したときにボタン項目が解放されないようにします。
2016年

30

Swift 3とSwift 4の場合、これを実行して以下を非表示にすることができますUIBarButtomItem

self.deleteButton.isEnabled = false
self.deleteButton.tintColor = UIColor.clear

そして示すためにUIBarButtonItem

self.deleteButton.isEnabled = true
self.deleteButton.tintColor = UIColor.blue

で、tintColor使用する原点の色を指定する必要があります。UIBarButtomItem


2
しかし、これはまだこのボタンのためのスペースを取ります。
Makalele

22

私は現在、iOS 7.1をターゲットとするOS X Yosemite Developer Preview 7およびXcode 6ベータ6を実行しており、次の解決策でうまくいきます。

  • UINavigationItemおよびUIBarButtonItemのアウトレットを作成します
  • 次のコードを実行して削除します

    [self.navItem setRightBarButtonItem:nil];
    [self.navItem setLeftBarButtonItem:nil];
    
  • 次のコードを実行してボタンを再度追加します

    [self.navItem setRightBarButtonItem:deleteItem];
    [self.navItem setLeftBarButtonItem:addItem];
    

ありがとう、これも私が見つけた最良の方法です。ボタンへの参照が強力であることを確認してください。
jyoung 2015

また、これはボタンが1つしかない場合にのみ機能することに注意してください。この例では、その側のすべてのボタンを削除します。
lnafziger 2015年

@jyoungこれは私にとってはうまくいきましたが、参照が強い場合になぜ重要なのですか?私は他の方法を試しませんでしたが、デフォルトではないので、通常はそのように設定しません。
ロバート

@Robert後でオブジェクトを使用するため、オブジェクトをnilに設定したときに、オブジェクトがガベージコレクションされないようにする必要があります。あなたがそれを取り除くためにそれがOKであるバーボタンアイテムを言ったときに他に何もオブジェクトを保持していなかったなら、それの参照カウントは0であり、それはガベージコレクションされます。
jyoung 2015年

14

私のプロジェクトではIBOutletsを使用しました。だから私の解決策は:

@IBOutlet weak var addBarButton: UIBarButtonItem!

addBarButton.enabled = false
addBarButton.tintColor = UIColor.clearColor()

そして、このバーを再び表示する必要がある場合は、反転したプロパティを設定します。

スウィフト3の代わりにenable使用してisEnableプロパティを。



12

iOS8。カスタム画像付きのUIBarButtonItem。多くの異なる方法を試しましたが、それらのほとんどは役に立ちませんでした。マックスの解決策は、setTintColorどの色にも変化していませんでした。私はこれを自分で見つけ、誰かに役立つと思った。

非表示の場合:

[self.navigationItem.rightBarButtonItem setEnabled:NO];
[self.navigationItem.rightBarButtonItem setImage:nil];

表示用:

[self.navigationItem.rightBarButtonItem setEnabled:YES];
[self.navigationItem.rightBarButtonItem setImage:image];

9

Swiftで試してみtintColorてください。AppDelegateのフォントサイズのようなUIBarButtonItemのデザインがある場合は更新しないでください。表示されたときにボタンの外観が完全に変更されます。

テキストボタンの場合、タイトルを変更するとボタンが「消える」可能性があります。

if WANT_TO_SHOW {
    myBarButtonItem.enabled = true
    myBarButtonItem.title = "BUTTON_NAME"
}else{
    myBarButtonItem.enabled = false
    myBarButtonItem.title = ""
}

7

私は、別のしわを発見tintColorし、isEnabledVoiceOverのは、アクセシビリティを有効になっていると、ボタンがされたとき-マックスと他の人によって提案されたアプローチ論理的にので、すなわち(それは「淡色表示」されていることを隠され、アクセシビリティカーソルがまだバーボタンに焦点を当て、および状態isEnabledIS falseに設定します)。受け入れられた回答のアプローチはこの副作用の影響を受けませんが、別の回避isAccessibilityElement策として、ボタンを「非表示にする」ときにfalseに設定しました。

deleteButton.tintColor = UIColor.clear
deleteButton.isEnabled = false
deleteButton.isAccessibilityElement = false

次にisAccessibilityElement、ボタンを「表示」するときにtrueに戻します。

deleteButton.tintColor = UIColor.blue
deleteButton.isEnabled = true
deleteButton.isAccessibilityElement = true

右のバーボタン項目の左端を非表示/表示していたので、バーボタン項目がまだスペースを占有することは問題ではありませんでした。


6
@IBDesignable class AttributedBarButtonItem: UIBarButtonItem {

    var isHidden: Bool = false {

        didSet {

            isEnabled = !isHidden
            tintColor = isHidden ? UIColor.clear : UIColor.black
        }
    }
}

そして今、単にisHiddenプロパティを変更します。


5

@lnafzigerからの回答の改善

Barbuttonsを強力なアウトレットに保存し、これを実行して非表示/表示します。

-(void) hideBarButtonItem :(UIBarButtonItem *)myButton {
    // Get the reference to the current toolbar buttons
    NSMutableArray *navBarBtns = [self.navigationItem.rightBarButtonItems mutableCopy];

    // This is how you remove the button from the toolbar and animate it
    [navBarBtns removeObject:myButton];
    [self.navigationItem setRightBarButtonItems:navBarBtns animated:YES];
}


-(void) showBarButtonItem :(UIBarButtonItem *)myButton {
    // Get the reference to the current toolbar buttons
    NSMutableArray *navBarBtns = [self.navigationItem.rightBarButtonItems mutableCopy];

    // This is how you add the button to the toolbar and animate it
    if (![navBarBtns containsObject:myButton]) {
        [navBarBtns addObject:myButton];
        [self.navigationItem setRightBarButtonItems:navBarBtns animated:YES];
    }
}

必要に応じて、以下の機能を使用してください。

[self showBarButtonItem:self.rightBarBtn1];
[self hideBarButtonItem:self.rightBarBtn1];

5

設定barButton.customView = UIView()してトリックを見るだけ


この答えが行うことは、すべての柔軟なサイズ設定を機能させることです。それは実際には非常に効率的な答えです。おそらく、拡張機能と組み合わせると完璧でしょう。
Adrian_H 2018

4

UIBarButtonItemを「非表示」にする方法はありません。UIViewButtonItemをsuperViewから削除し、再度表示する場合は追加し直す必要があります。


これは実際には真実ではありません-マックスによって記述された方法はうまくいきます。
ノーザン

1
nothernman-Maxは実際には正しくありません。彼は実際、ほとんどの人が「隠す」と定義する方法でボタンを隠しています。彼は単にそれを非表示にし、ユーザーの操作を無効にしています。ボタンはまだそこにあり、スペースをとります。それはあなたが「隠す」をどのように定義したいかにかかっています、私は元の質問の精神が単にそれを見えなくするだけでなく、実際にそれを削除/追加したいと思っていたと思います。
マイケルピーターソン

4

これは回答リストのかなり下にありますが、誰かが簡単なコピーと貼り付けを迅速な解決策のために望んでいる場合に備えて、ここにあります

func hideToolbarItem(button: UIBarButtonItem, withToolbar toolbar: UIToolbar) {
    var toolbarButtons: [UIBarButtonItem] = toolbar.items!
    toolbarButtons.removeAtIndex(toolbarButtons.indexOf(button)!)
    toolbar.setItems(toolbarButtons, animated: true)
}

func showToolbarItem(button: UIBarButtonItem, inToolbar toolbar: UIToolbar, atIndex index: Int) {
    var toolbarButtons: [UIBarButtonItem] = toolbar.items!
    if !toolbarButtons.contains(button) {
        toolbarButtons.insert(button, atIndex: index)
        toolbar.setItems(toolbarButtons, animated:true);
    }
}

悪くはありませんが、UIToolButtonではなくUINavigationItemをパラメーターとして指定する必要があります。UIBarbarはUIBarButtonItemを非表示にするように求められるためです。関数を次のように変更しました:func hideToolbarItem(button:UIBarButtonItem、withToolbar toolbar:UINavigationItem){var toolbarButtons:[UIBarButtonItem] = toolbar.rightBarButtonItems!toolbarButtons.removeAtIndex(toolbarButtons.indexOf(button)!)toolbar.setRightBarButtonItems(toolbarButtons、animated:true)}これはすばらしいことです
Kingalione

3

これを行う1つの方法initWithCustomView:(UIView *)は、を割り当てるときにのプロパティを使用することです UIBarButtonItem。のサブクラスにUIViewは、非表示/再表示プロパティがあります。

例えば:

1.持っているUIButtonあなたは、表示/非表示にしたいです。

2.UIButtonカスタムビューとして作成します。お気に入り :

UIButton*myButton=[UIButton buttonWithType:UIButtonTypeRoundedRect];//your button

UIBarButtonItem*yourBarButton=[[UIBarButtonItem alloc] initWithCustomView:myButton];

3.myButton作成したを非表示/再表示できます。[myButton setHidden:YES];


ただし、他のボタン間のギャップはなくなりません。「非表示」にすると、ツールバーに空の領域ができます。
lnafziger 2012

@lnafzigerはい、そうですが、ボタン間のギャップを閉じることについてのOPの説明は読みませんでしたが、注意する必要があります。
iNoob 2012

1
ありがとう、あなたの答えも役に立ちますが、ツールバーのボタンを非表示にしたい場合、ほとんどの人はボタンがまったくないように見せたいと思います(空白の領域なし)。それが左か右のどちらかであるなら、それは実際に重要ではないでしょう。
lnafziger 2012

良い点、iNoobとInafziger-どちらの方法でも言及しませんでしたが、はい、空白のスポットがないことを望みます。
Sasha

3

Swiftバージョンの場合、コードは次のとおりです。

の場合UINavigationBar

self.navigationItem.rightBarButtonItem = nil

self.navigationItem.leftBarButtonItem = nil

2

バーボタンの項目が無効になっているときにテキストの色をクリアな色に設定することは、おそらくよりクリーンなオプションです。コメントで説明しなければならない奇妙さはありません。また、ボタンを破棄しないので、関連するストーリーボードセグエを維持できます。

[self.navigationItem.rightBarButtonItem setTitleTextAttributes:@{NSForegroundColorAttributeName:[UIColor clearColor]}
                                                      forState:UIControlStateDisabled];

次に、バーボタンアイテムを非表示にしたい場合は、次のようにします。

self.navigationItem.rightBarButton.enabled = NO;

隠されたプロパティがないのは不自然ですが、これは同じ結果を提供します。


1
rightBarButtonItem内にボタンがありました。そこで、有効化をNOに設定し、無効化時のイメージをnilに変更しました。チャームのように動作しました...ありがとう
Skywalker

優れたアイデアですが、画像をnullに設定してもうまくいきませんでした。20x20の小さな透明な四角形を画像として配置する必要がありました
Lena Bru

2

UIBarButtonItemにテキストの代わりに画像がある場合、これを実行して非表示にすることができます。 navigationBar.topItem.rightBarButtonItem.customView.alpha = 0.0;


2

それぞれに複数のツールバーと複数のボタンがあるため、lnafzigerの承認済みの回答に基づいて共有すると思われるいくつかのヘルパーメソッド:

-(void) hideToolbarItem:(UIBarButtonItem*) button inToolbar:(UIToolbar*) toolbar{
    NSMutableArray *toolbarButtons = [toolbar.items mutableCopy];
    [toolbarButtons removeObject:button];
    [toolbar setItems:toolbarButtons animated:NO];
}

-(void) showToolbarItem:(UIBarButtonItem*) button inToolbar:(UIToolbar*) toolbar atIndex:(int) index{
    NSMutableArray *toolbarButtons = [toolbar.items mutableCopy];
    if (![toolbarButtons containsObject:button]){
        [toolbarButtons insertObject:button atIndex:index];
        [self setToolbarItems:toolbarButtons animated:YES];
    }
}

2

この方法でビューを簡単に取得して非表示にすることができます

let view: UIView = barButtonItem.valueForKey("view") as! UIView
view.hidden = true


2

これを処理する拡張機能を次に示します。

extension UIBarButtonItem {

    var isHidden: Bool {
        get {
            return tintColor == .clear
        }
        set {
            tintColor = newValue ? .clear : .white //or whatever color you want
            isEnabled = !newValue
            isAccessibilityElement = !newValue
        }
    }

}

使用法:

myBarButtonItem.isHidden = true

1

Eli Burkeの応答を補完しUIBarButtonItem、タイトルの代わりに背景画像がある場合は、コードを使用できます。

-(void)toggleLogoutButton:(bool)show{
    if (show) {
        self.tabButton.style = UIBarButtonItemStyleBordered;
        self.tabButton.enabled = true;
        UIImage* imageMap = [UIImage imageNamed:@"btn_img.png"];
        [((UIButton *)[self.tabButton customView]) setBackgroundImage:imageMap forState:UIControlStateNormal];
    } else {
        self.tabButton.style = UIBarButtonItemStylePlain;
        self.tabButton.enabled = false;
        [((UIButton *)[self.tabButton customView]) setBackgroundImage:nil forState:UIControlStateNormal];
    }
}

0

toolbar.items配列を操作する必要があります。

以下は、[完了]ボタンを非表示にして表示するために使用するコードです。ボタンがツールバーの最端または他のボタンの間にある場合、他のボタンが移動するため、ボタンを単に非表示にしたい場合は、ボタンを中央に向かって最後のボタンとして配置します。私は効果のためにボタンの動きをアニメーション化します、私はそれがとても好きです。

-(void)initLibraryToolbar {

    libraryToolbarDocumentManagementEnabled = [NSMutableArray   arrayWithCapacity:self.libraryToolbar.items.count];
    libraryToolbarDocumentManagementDisabled = [NSMutableArray arrayWithCapacity:self.libraryToolbar.items.count];
    [libraryToolbarDocumentManagementEnabled addObjectsFromArray:self.libraryToolbar.items];
    [libraryToolbarDocumentManagementDisabled addObjectsFromArray:self.libraryToolbar.items];
    trashCan = [libraryToolbarDocumentManagementDisabled objectAtIndex:3];
    mail = [libraryToolbarDocumentManagementDisabled objectAtIndex:5];
    [libraryToolbarDocumentManagementDisabled removeObjectAtIndex:1];
    trashCan.enabled = NO;
    mail.enabled = NO;
    [self.libraryToolbar setItems:libraryToolbarDocumentManagementDisabled animated:NO];

}

これで、次のコードを使用してボタンを表示できます

[self.libraryToolbar setItems:libraryToolbarDocumentManagementEnabled animated:YES];
trashCan.enabled = YES;
mail.enabled = YES; 

またはボタンを非表示にする

[self.libraryToolbar setItems:libraryToolbarDocumentManagementDisabled animated:YES];
trashCan.enabled = NO;
mail.enabled = NO;

0

IBでは、ボタンのタイトルを空白のままにすると表示されません(初期化されていませんか?)。開発中にUIの更新中にバーボタンアイテムを一時的に非表示にして、削除せずにすべてのアウトレット参照を破棄する場合、これを頻繁に行います。

これは実行時に同じ効果はありません。ボタンのタイトルをnilに設定しても、ボタン全体が非表示になることはありません。申し訳ありませんが、実際には質問の答えにはなりませんが、一部の人にとっては役立つ場合があります。

編集:このトリックは、ボタンのスタイルがプレーンに設定されている場合にのみ機能します


0

ここではまだ言及されていないため、ここにソリューションを追加します。1つのコントロールの状態に応じて画像が変化する動的ボタンがあります。私にとって最も簡単な解決策はnil、コントロールが存在しない場合に画像を設定することでした。コントロールが更新されるたびに画像が更新されたため、これは私にとって最適でした。念のため、もに設定しenabledていNOます。

幅を最小値に設定すると、iOS 7では機能しませんでした。


0

@ lnafziger、@ MindSpiker、@ vishalなどの功績によるものです。al、

右(または左)の1つのバーボタン用に到達した最も単純な1ライナーは次のとおりです。

self.navigationItem.rightBarButtonItem = <#StateExpression#>
    ? <#StrongPropertyButton#> : nil;

のように:

@interface MyClass()

@property (strong, nonatomic) IBOutlet UIBarButtonItem *<#StrongPropertyButton#>;

@end

@implementation

- (void) updateState
{
    self.navigationItem.rightBarButtonItem = <#StateExpression#>
        ? <#StrongPropertyButton#> : nil;
}

@end

私はこれをテストし、それは私のために動作します(IB経由で配線された強力なバーボタン項目で)。


これはボタンが1つしかない場合は機能しますが、ボタンが複数ある場合は、私の答えのとおりにメソッドを使用する必要があります。
lnafziger 14
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.