lakshmen
lakshmen

Reputation: 29094

Weird error in accessing the text of UIButton in swift

When I write a simple function such as this:

@IBAction func buttonTapped(theButton:UIButton) {
        println(theButton.titleLabel.text);
    }

It gives me an error: UILabel doesn't have a label called text.

However, when I change it to this:

@IBAction func buttonTapped(theButton:UIButton) {
        println(theButton.titleLabel?.text);
    }

It works fine, but it prints out something like this:

Optional("1");

What I am doing wrong? I am expecting a value of 1. But it is printing out Optional("1") and secondly, it is working fine when println(theButton.titleLabel?.text);

Upvotes: 0

Views: 1711

Answers (5)

Jeffrey Neo
Jeffrey Neo

Reputation: 3809

You can get directly from

let title = theButton.currentTitle!

Upvotes: 4

Kirsteins
Kirsteins

Reputation: 27345

Optional chaining makes the result optional, so you are printing optional value: https://developer.apple.com/library/ios/documentation/swift/conceptual/Swift_Programming_Language/OptionalChaining.html

With optional binding you can print the value only if it exits.

if let text = theButton.titleLabel?.text {
    println(text)
} else {
    // text doesn't have value
}

Upvotes: 2

Antonio
Antonio

Reputation: 72770

@Kirsteins's answer shows how to obtain the button label text in a safe manner.

Remember that:

  • UIButton has a titleLabel, which is an optional UILabel.
  • UILabel has a text property, which is an optional String

so there are 2 optionals in the chain. You can use optional binding as in @Kirsteins's answer, or use forced unwrapping:

let text = theButton.titleLabel!.text!

which however I discourage using, because if any of the 2 is nil you'll have a runtime exception. But for completeness it's worth mentioning.

Upvotes: 2

Nicos Karalis
Nicos Karalis

Reputation: 3773

Kirsteins answers it correctly but misses one small detail

if your object can be nil (optional) you need to check first if it exists to then access its value, like this:

if let text = theButton.titleLabel?.text {
    println(text)
}

but you can also ignore the if and just call it like this:

let text : String = theButton.titleLabel?.text
// If theButton.titleLabel don't exists then text will be nil

this happen if the IBOutlet was declared with ? but if you declare with ! that means you know that it could be nil, but you never want it to be nil, for a IBOutlet i prefer this approach since if the IBOutlet is not connected then maybe something is worn with my code.

@IBOutlet var theButton : UIButton!
// and get text value as
theButton.titleLabel!.text

this will ensure theButton.titleLabel could be nil, but in this part of code it is required, hope this helps to understand the difference between optional (?) and optional required (!)

Upvotes: 0

Marius Fanu
Marius Fanu

Reputation: 6669

The buttons titleLabel property returns an optional UILabel, that means it's possible that the button doesn't have a titleLabel.

var titleLabel: UILabel? { get }

If you don't set a title to the button, then the button doesn't have a titleLabel property, the iOS framework adds the titleLabel only if the button has a title, I think this happens to reduce memory.

This is why you have to put the "?" (is called optional chaining you can read about it here http://bit.ly/1vrSOi1) in that line, but this usually get auto completed by Xcode itself.

Upvotes: 0

Related Questions