Make a UIBarButtonItem disappear using swift IOS
Asked Answered
S

18

41

I have an IBOutlet that I have linked to from the storyboard

@IBOutlet var creeLigueBouton: UIBarButtonItem!

and I want to make it disappear if a condition is true

if(condition == true)
{
    // Make it disappear
}
Stubstad answered 25/8, 2014 at 18:51 Comment(0)
G
41

Do you really want to hide/show creeLigueBouton? It is instead much easier to enable/disable your UIBarButtonItems. You would do this with a few lines:

if(condition == true) {
    creeLigueBouton.enabled = false
} else {
    creeLigueBouton.enabled = true
}

This code can even be rewritten in a shorter way:

creeLigueBouton.enabled = !creeLigueBouton.enabled

Let's see it in a UIViewController subclass:

import UIKit

class ViewController: UIViewController {

    @IBOutlet weak var creeLigueBouton: UIBarButtonItem!

    @IBAction func hide(sender: AnyObject) {
        creeLigueBouton.enabled = !creeLigueBouton.enabled
    }

}

If you really want to show/hide creeLigueBouton, you can use the following code:

import UIKit

class ViewController: UIViewController {

    var condition: Bool = true
    var creeLigueBouton: UIBarButtonItem! //Don't create an IBOutlet

    @IBAction func hide(sender: AnyObject) {
        if(condition == true) {
            navigationItem.rightBarButtonItems = []
            condition = false
        } else {
            navigationItem.rightBarButtonItems = [creeLigueBouton]
            condition = true
        }
    }

    override func viewDidLoad() {
        super.viewDidLoad()

        creeLigueBouton = UIBarButtonItem(title: "Creer", style: UIBarButtonItemStyle.Plain, target: self, action: "creerButtonMethod")
        navigationItem.rightBarButtonItems = [creeLigueBouton]
    }

    func creerButtonMethod() {
        print("Bonjour")
    }

}
Gatehouse answered 25/8, 2014 at 23:53 Comment(3)
And for a disabled button is it possible to modify the text color?Garvy
was looking for a long time, this is the perfect answer till now.Policewoman
As of iOS 16, UIBarButtonItem has its own isHidden property so none of this is necessary. See this answer.Abirritate
S
53

Use the property enabled and tintColor

    let barButtonItem:UIBarButtonItem? = nil

    if isHidden{
        barButtonItem?.enabled      = false
        barButtonItem?.tintColor    = UIColor.clearColor()
    }else{
        barButtonItem?.enabled      = true
        barButtonItem?.tintColor    = nil
    }
Stride answered 21/10, 2015 at 3:59 Comment(3)
Thanks, mate! Worked for me.Petronille
Awesome! Works wellMotorize
As of iOS 16, UIBarButtonItem has its own isHidden property so none of this is necessary. See this answer.Abirritate
G
41

Do you really want to hide/show creeLigueBouton? It is instead much easier to enable/disable your UIBarButtonItems. You would do this with a few lines:

if(condition == true) {
    creeLigueBouton.enabled = false
} else {
    creeLigueBouton.enabled = true
}

This code can even be rewritten in a shorter way:

creeLigueBouton.enabled = !creeLigueBouton.enabled

Let's see it in a UIViewController subclass:

import UIKit

class ViewController: UIViewController {

    @IBOutlet weak var creeLigueBouton: UIBarButtonItem!

    @IBAction func hide(sender: AnyObject) {
        creeLigueBouton.enabled = !creeLigueBouton.enabled
    }

}

If you really want to show/hide creeLigueBouton, you can use the following code:

import UIKit

class ViewController: UIViewController {

    var condition: Bool = true
    var creeLigueBouton: UIBarButtonItem! //Don't create an IBOutlet

    @IBAction func hide(sender: AnyObject) {
        if(condition == true) {
            navigationItem.rightBarButtonItems = []
            condition = false
        } else {
            navigationItem.rightBarButtonItems = [creeLigueBouton]
            condition = true
        }
    }

    override func viewDidLoad() {
        super.viewDidLoad()

        creeLigueBouton = UIBarButtonItem(title: "Creer", style: UIBarButtonItemStyle.Plain, target: self, action: "creerButtonMethod")
        navigationItem.rightBarButtonItems = [creeLigueBouton]
    }

    func creerButtonMethod() {
        print("Bonjour")
    }

}
Gatehouse answered 25/8, 2014 at 23:53 Comment(3)
And for a disabled button is it possible to modify the text color?Garvy
was looking for a long time, this is the perfect answer till now.Policewoman
As of iOS 16, UIBarButtonItem has its own isHidden property so none of this is necessary. See this answer.Abirritate
P
14
// Nice answer haiLong, I think as an extension this is more convenient.

extension UIBarButtonItem {
    var isHidden: Bool {
        get {
            return !isEnabled && tintColor == .clear
        }
        set {
            tintColor = newValue ? .clear : nil
            isEnabled = !newValue
        }
    }
}

EDIT: Removed forced unwrapping and fixed enabled value.

Pentode answered 3/8, 2016 at 5:22 Comment(2)
This is great but it doesn't work if your UIBarButtonItem contains a customView, if it does you can call hidden on that view directly.Soriano
As of iOS 16.0, UIBarButtonItem has its own isHidden property. This extension is no longer needed.Abirritate
P
13

For Swift 3

if (your_condition) {
  self.navigationItem.rightBarButtonItem = self.addAsset_btn
 }
else {
  // hide your button
  self.navigationItem.rightBarButtonItem = nil
 }
Paint answered 25/10, 2016 at 7:17 Comment(0)
F
6

First way:

Just set .title to ""

Second way:

Just call updateToolBar() whenever you want to show/hide the creeLigueBouton.

func updateToolBar() {
    var barItems: [UIBarButtonItem] = []

    if condition != true {
        // Make it appear
        barItems.append(creeLigueBouton)
    }

    barItems.append(anotherButton)

    myToolBar.setItems(barItems, animated: true)

    myToolBar.setNeedsLayout()
}
Facer answered 7/7, 2015 at 5:56 Comment(3)
@JSA986 yeah... thats trueMart
(second way works even if the bar button item has no title)Mart
Second way doesn't work unless you create a strong outlet reference or instantiate your button programmaticallyBellow
A
4

The following solution works for me.

        var skipButton: UIButton = UIButton.buttonWithType(UIButtonType.Custom) as UIButton
    skipButton.frame = CGRectMake(10.0, 0.0, 58.0, 32.0);
    skipButton.setTitle("Skip", forState: UIControlState.Normal)
    skipButton.setTitleColor(UIColor(red: 0.0, green: 122.0/255.0, blue: 255.0/255.0, alpha: 1.0), forState: UIControlState.Normal)
    skipButton.addTarget(self, action: "rightButtonAction:", forControlEvents: UIControlEvents.TouchUpInside)
    var skipButtonItem = UIBarButtonItem(customView: skipButton)
    self.navigationItem.rightBarButtonItem = skipButtonItem;

    if hideSkipButton == true {
        self.navigationItem.rightBarButtonItem = nil
    } 
Absinthe answered 22/1, 2015 at 10:5 Comment(0)
L
3

heres my solution:

hide:

self.creeLigueBouton.title = ""
self.creeLigueBouton.style = UIBarButtonItemStyle.Plain
self.creeLigueBouton.enabled = false

show:

self.creeLigueBouton.title = "Original Button Text"
self.creeLigueBouton.style = UIBarButtonItemStyle.Bordered
self.creeLigueBouton.enabled = true
Leggy answered 18/7, 2015 at 5:54 Comment(0)
F
3

It is quite late to reply but looking for an answer for my problem I found this topic. The marked answer did not help me, but I managed to solve my problem thanks to @haiLong's answer. My solution works for all types of bar buttons... I think. Add this to your ViewController and use as needed.

var tintColorsOfBarButtons = [UIBarButtonItem: UIColor]()

    func hideUIBarButtonItem(button: UIBarButtonItem) {
        if button.tintColor != UIColor.clear {
            tintColorsOfBarButtons[button] = button.tintColor
            button.tintColor = UIColor.clear
            button.isEnabled = false
        }
    }

    func showUIBarButtonItem(button: UIBarButtonItem) {
        if tintColorsOfBarButtons[button] != nil {
            button.tintColor = tintColorsOfBarButtons[button]
        }
        button.isEnabled = true
    }

I hope it saves some time to other developers :)

Fenske answered 25/10, 2017 at 9:39 Comment(0)
M
2

If you have set of UIBarButtonItems to hide, e.g. only show them on Landscape orientation, and hide or Portrait, you can use tag and Swift Array's filter. Let's assume we made @IBOutlet link to UIToolBar:

@IBOutlet weak var toolbar: UIToolbar!

First, we save toolbar's items in viewDidLoad:

override func viewDidLoad() {
  super.viewDidLoad()
  // Do any additional setup after loading the view, typically from a nib.
  toolbarItems = toolbar.items
}

Set the tag property of UIBarButtonItem you want to show on Landscape orientation to 1 or whatever you like. Then, override func traitCollectionDidChange

override func traitCollectionDidChange(previousTraitCollection: UITraitCollection?) {
    super.traitCollectionDidChange(previousTraitCollection)

    switch (traitCollection.horizontalSizeClass, traitCollection.verticalSizeClass) {
    case (.Compact, .Regular): // iPhone Portrait
      let items: [UIBarButtonItem]?
      if view.frame.width > 320 { // iPhone 6 & 6S
        items = toolbarItems?.filter({ $0.tag < 5 })
      } else { 
        items = toolbarItems?.filter({ $0.tag < 4 })
      }
      bottomToolbar.setItems(items, animated: true)
    case (_, .Compact): // iPhone Landscape
      let items = toolbarItems?.filter({ $0.tag < 6 })
      bottomToolbar.setItems(items, animated: true)
    default: // iPad
      break
    }
  }

In this example, I set all UIBarButtonItem's tag for iPad only to 6, iPhone Landscape to 5, and for iPhone 6 & 6+ to 4.

Marni answered 26/7, 2015 at 13:56 Comment(0)
M
1

I did it using this:

navigationItem.setHidesBackButton(true, animated: true)
Mollie answered 10/9, 2015 at 14:43 Comment(1)
Exactly what I was looking for, thanks for posting your solutionLenhard
R
1

I have more that 2 menuitems and remove/add menuitem is an overhead. This code snippet worked for me (Using Swift3).

func showMenuItem(){

    menuItemQuit.customView?.isHidden = false
    menuItemQuit.plainView.isHidden = false
}

func hideMenuItem(){

    menuItemQuit.customView?.isHidden = true
    menuItemQuit.plainView.isHidden = true
}
Rookie answered 6/6, 2017 at 9:41 Comment(0)
U
0

I had the same problem with a tool bar that I had to hide and show its last button. So I declared a var to hold the UIBarButtonItem and removed it from the bar or added depending on the situation like:

inside the class declared the var and linked the toolbar:

var buttonToHide : UIBarButtonItem?

@IBOutlet weak var toolbarOne: UIToolbar!

at the viewDidLoad :

buttonToHide = toolbarOne.items![toolbarOne.items!.count - 1] as? UIBarButtonItem

in my code I made the trick:

if situationOccurrsToHide {
   toolbarOne.items!.removeLast()
}

or

if situationOccursToShow 
{    
   toolbarOne.items!.append(buttonToHide!) 
}

You can use the removeAtIndex or insert(buttonToHide, atIndex: xx) to remove or reinsert the button at a specific position.

You must be careful not to insert or remove the button more than once.

Hope it helps.

Unmannered answered 4/3, 2015 at 22:12 Comment(0)
E
0

You can use text attributes to hide a bar button:

barButton.enabled = false
barButton.setTitleTextAttributes([NSForegroundColorAttributeName : UIColor.clearColor()], forState: .Normal)

Also I've made extension for UIBarButtonItem with a hidden property:

extension UIBarButtonItem {

    var titleTextAttributes: [NSObject : AnyObject]! {
        set {
            setTitleTextAttributes(newValue, forState: .Normal)
        }

        get {
            return titleTextAttributesForState(.Normal)
        }

    }

    private static var savedAttributesKey = "savedAttributes"

    var savedAttributes: [NSObject : AnyObject]? {
        set {
            objc_setAssociatedObject(self, &UIBarButtonItem.savedAttributesKey, newValue, UInt(OBJC_ASSOCIATION_RETAIN_NONATOMIC))
        }
        get {
            return objc_getAssociatedObject(self, &UIBarButtonItem.savedAttributesKey) as? [NSObject : AnyObject]
        }
    }

    var hidden: Bool {
        set {
            enabled = !newValue

            if newValue {
                savedAttributes = titleTextAttributes

                // Set a clear text color
                var attributes = titleTextAttributes
                attributes[NSForegroundColorAttributeName] = UIColor.clearColor()
                titleTextAttributes = attributes
            }
            else {
                titleTextAttributes = savedAttributes
            }
        }

        get {
            return enabled
        }
    }
}
Estevez answered 21/8, 2015 at 11:34 Comment(0)
S
0

Try this. (Make newbackbutton global variable)

override func viewDidLoad() {

    let newBackButton = UIBarButtonItem()

     newBackButton.title = " << Return to Gallery"
    newBackButton.style  = UIBarButtonItemStyle.Done
    newBackButton.target = self
    newBackButton.action = "backtoScoutDetail:"
    self.navigationItem.rightBarButtonItem = newBackButton

}

override func viewWillAppear(animated: Bool) {

    newBackButton.title = ""
    self.navigationItem.rightBarButtonItem = newBackButton        

     }
Safeguard answered 3/9, 2015 at 13:20 Comment(0)
T
0

For Swift 5:

self.viewController?.navigationItem.setLeftBarButton(nil, animated: true)

If you're using isPreparingForSegue, you can easily adapt that so the next modal won't show like an hide button but the "back" button. :)

segue.destination.navigationItem.setLeftBarButton(nil, animated: true)

Teshatesla answered 5/4, 2022 at 9:33 Comment(1)
What about this is specific to Swift 5?Abirritate
F
0

To really remove the button and reclaim the space in the bar that it used you can do it this way:

  • fetch the array of left or right bar button items you want to alter
  • search for the index of your button and remove it
  • set the updated array to the navigationItem

This is only a quick example and does contain forced optional downcasts for simplicity - I encourage you to replace them with checks. I tested it in viewDidLoad() and it works for my purpose (removing items added in interface builder for some use cases).

var items = navigationItem.rightBarButtonItems
items!.remove(at: items!.firstIndex(of: myUIBarButton)!)
navigationItem.rightBarButtonItems = items
Ferruginous answered 18/11, 2022 at 15:2 Comment(0)
A
0

As of iOS 16.0 UIBarButtonItem has an isHidden property. Simply set that based on your condition:

if condition {
    creeLigueBouton.isHidden = true
}

Of course you probably want to set isHidden to false if the condition is not true. Or more simply:

creeLigueBouton.isHidden = condition
Abirritate answered 14/12, 2023 at 15:59 Comment(0)
S
-1
Try these:

 self.navigationController?.navigationBar.backItem?.title = ""
        navigationItem.backBarButtonItem?.title = ""
        navigationItem.leftBarButtonItem?.title = ""
navigationItem.hidesBackButton = true


        navigationItem.setLeftBarButtonItem(nil, animated: true)
        navigationItem.setRightBarButtonItem(nil, animated: true)
Safeguard answered 4/1, 2016 at 9:16 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.