Setting bar button item image to system item programmatically—Swift

7.3k Views Asked by At

I have a bar button item set to a custom image from my image assets folder. After launch, once the user presses the button, I want it to change to a system item—the stop (X) button. I know how to programmatically change the image of the bar button, but how do I change the image to one of the system items in my code?

Swift 3, Xcode 8 beta 1.

Edit Here are the system items I'm referencing: Xcode system items

How can I change my button's image to one of those system items from my code?

3

There are 3 best solutions below

5
Alonso Urbano On

What you need to do is to have two buttons (you can set them programmatically or in interface builder), one with the image and another one with the stop behavior. When one is pressed, toggle the visibility of both.

I believe the best option is to do it programmatically, so this is how:

Add two bar button items as class members:

private var itemOn: UIBarButtonItem!
private var itemOff: UIBarButtonItem!

Then in the viewDidLoad set the values as you want (one to have an image, the other to have the normal behavior with the "X"). Then add the itemOn button to the navigation bar:

self.navigationItem.rightBarButtonItem = itemOn

Be aware that both should have the same action:

self.itemOn.target = self
self.itemOn.action = Selector("toggleVisibleButton:")
self.itemOff.target = self
self.itemOff.action = Selector("toggleVisibleButton:")

Then implement the toggleVisibleButton function:

func toggleVisibleButton(sender: UIBarButtonItem) {
    if self.navigationItem.rightBarButtonItem == itemOn {
        self.navigationItem.rightBarButtonItem = itemOff
        // Do something with the button that has the image
    } else {
        self.navigationItem.rightBarButtonItem = itemOn
        // Do something with the button that has the X
    }
}

Update for Swift 3:

Set the action like this:

self.itemOn.action = #selector(self.toggleVisibleButton(sender:))
0
blanNL On
navigationItem.rightBarButtonItem = UIBarButtonItem(
    barButtonSystemItem: UIBarButtonItem.SystemItem.add, 
    target: self, 
    action: #selector(yourMethod)
)

Change 'add' according to https://developer.apple.com/documentation/uikit/uibarbuttonitem/systemitem

0
Michael On

For those of you using iOS 13 & up, you can use the UIImage(systemName:) property. You can search the systemItem names and corresponding images using Apple's SF Symbols app. Here's an example using the stop X button:

barButtonItem.image = UIImage(systemName: "xmark")