p.a.'s answer, converted for Xcode 9, Swift 4.
The idea is that the .done
style highlights - or bolds, in Swift 4 - the button text.
Initialize the button item in an un-highlighted state:
let toggleButtonItem = UIBarButtonItem(title: "MyButton",
style: .plain,
target: self,
action: #selector(doSomething))
Toggle the button item to a highlighted state using a ternary operator, like so:
toggleButtonItem.style = (toggleButtonItem.style == .plain) ?
toggleButtonItem.style = .done : toggleButtonItem.style = .plain
Or, alternatively, toggle the highlight state with a regular if/else
statement like this instead:
if toggleButtonItem.style == .plain {
toggleButtonItem.style = .done
}
else {
toggleButtonItem.style = .plain
}
And, to set up a boolean value to check if the button item is highlighted:
var isHighlighted: Bool = (toggleButtonItem.style == .done)
Notes:
- The
bordered
style was deprecated in iOS 8, so I used .plain
here instead. They both present the button item's text in an unhighlighted state.
The #selector
function must either be an @IBAction
, or it must be prefixed with @objc
, to avoid "Objective-C inference" issues. For example:
@objc func doSomething() { ... }
or, if you've connected an action to the button item:
@IBAction func doSomething() { ... }
Both of these function declarations tell the compiler that they're using Objective-C-based functionality. This is required because #selector
is an Objective-C thing under the hood, and in Swift 4 you have to state this, rather than letting the compiler infer what's going on as it has done previously.