Interface builder not setting button title?

I'm just learning how to build apps using Swift and Xcode. I'm following along through the Xcode Fundamentals book, and ran into an issue in the "Apple Pie" project. When you tap a button, the button is supposed to reference the button title and set a variable to the button title, but the title instead comes through as "nil" and the app crashes, even though a title is set in interface builder.

I created a basic new app to test how I think this code should be working - see screenshots.

When the button (title: Aaron) is tapped, the console should print the button title, but instead I'm getting the "nil" value. What am I missing here?

Answered by Claude31 in 692444022

That confirms that the reason is that the button is not in normal state and that its title for normal state is not defined. Which is surprising.

Which version of Xcode do you use ?

Could you do another test by printing in the IBAction:

          print("normal", sender.title(for: .normal))
          print("highlighted", sender.title(for: .highlighted))
          print("disabled", sender.title(for: .disabled))
          print("selected", sender.title(for: .selected))
          print("focused", sender.title(for: .focused))

I tested with the same button definition (Style plain). It works and the sender button content is the same as yours:

<UIButton: 0x7fa72e70b990; frame = (99 664; 214 34.3333); opaque = NO; autoresize = RM+BM; layer = <CALayer: 0x600003c315e0>> configuration=<UIButtonConfiguration: 0x600000073100> baseStyle=plain macStyle=automatic buttonSize=medium cornerStyle=dynamic title=<0x600003c31760>:'Aaron' contentInsets=default imagePlacement=leading imagePadding=0 titlePadding=1 titleAlignment=automatic automaticallyUpdateForSelection background=<UIBackgroundConfiguration: 0x60000096b300; Base Style = Custom; cornerRadius = 5.95; backgroundColor = UIExtendedGrayColorSpace 0 0>

Could you test with a default style for button, instead of plain ?

I cannot find anything wrong in this small code.

And the fact it prints nil shows the action is correctly connected.

A possible reason would be the state of button is not normal.

I tried with the exact same button definition and it works.

Could you try :

  • to be sure of what is called, replace print by
print(#function, sender.title(for: .normal))
print("Sate", sender.state)
  • add a print to test the titleLabel
          print(sender.titleLabel)
  • and test the button itself:
print(sender)
print(button)

What do you get ?

Did you copy the code exactly ?

Screenshot of code attached- I copied and pasted directly from your comment.

Output from console:

buttonPressed(_:) nil

Sate UIControlState(rawValue: 1)

Optional(<UILabel: 0x7f810f80dcf0; frame = (20 5.33333; 45 20.3333); text = 'Aaron'; userInteractionEnabled = NO; layer = <_UILabelLayer: 0x60000028be30>>)

<UIButton: 0x7f810e70b9e0; frame = (167 433; 85 31); opaque = NO; autoresize = RM+BM; layer = <CALayer: 0x6000021ba480>> configuration=<UIButtonConfiguration: 0x600001d9c700> baseStyle=plain macStyle=automatic buttonSize=medium cornerStyle=dynamic title=<0x6000021d2280>:'Aaron' contentInsets=default imagePlacement=leading imagePadding=0 titlePadding=1 titleAlignment=automatic automaticallyUpdateForSelection background=<UIBackgroundConfiguration: 0x600001498600; Base Style = Custom; cornerRadius = 5.95; backgroundColor = UIExtendedGrayColorSpace 0 0>

Optional(<UIButton: 0x7f810e70b9e0; frame = (167 433; 85 31); opaque = NO; autoresize = RM+BM; layer = <CALayer: 0x6000021ba480>> configuration=<UIButtonConfiguration: 0x600001d9c700> baseStyle=plain macStyle=automatic buttonSize=medium cornerStyle=dynamic title=<0x6000021d2280>:'Aaron' contentInsets=default imagePlacement=leading imagePadding=0 titlePadding=1 titleAlignment=automatic automaticallyUpdateForSelection background=<UIBackgroundConfiguration: 0x600001498600; Base Style = Custom; cornerRadius = 5.95; backgroundColor = UIExtendedGrayColorSpace 0 0>)
Accepted Answer

That confirms that the reason is that the button is not in normal state and that its title for normal state is not defined. Which is surprising.

Which version of Xcode do you use ?

Could you do another test by printing in the IBAction:

          print("normal", sender.title(for: .normal))
          print("highlighted", sender.title(for: .highlighted))
          print("disabled", sender.title(for: .disabled))
          print("selected", sender.title(for: .selected))
          print("focused", sender.title(for: .focused))

I tested with the same button definition (Style plain). It works and the sender button content is the same as yours:

<UIButton: 0x7fa72e70b990; frame = (99 664; 214 34.3333); opaque = NO; autoresize = RM+BM; layer = <CALayer: 0x600003c315e0>> configuration=<UIButtonConfiguration: 0x600000073100> baseStyle=plain macStyle=automatic buttonSize=medium cornerStyle=dynamic title=<0x600003c31760>:'Aaron' contentInsets=default imagePlacement=leading imagePadding=0 titlePadding=1 titleAlignment=automatic automaticallyUpdateForSelection background=<UIBackgroundConfiguration: 0x60000096b300; Base Style = Custom; cornerRadius = 5.95; backgroundColor = UIExtendedGrayColorSpace 0 0>

Could you test with a default style for button, instead of plain ?

Xcode Version 13.0 (13A233).

console output:

normal nil

highlighted nil

disabled nil

selected nil

focused nil

edit: I just updated the style from plain to default - heres the output. I think good things happened

normal Optional("Aaron")

highlighted Optional("Aaron")

disabled Optional("Aaron")

selected Optional("Aaron")

focused Optional("Aaron")

It is a known issue that Apple Pie thing does not work well with Xcode 13.

(It is very easily reproducible with creating a brand new project in Xcode 13.)

These are some example threads:

Guided Project: Apple Pie

Apple Pie Guided Project: getting error - Thread 1: Fatal error: Unexpectedly found nil while unwrapping an Optional value.

Wow guys thanks so glad I found this! So the problem that's happening is that on Xcode 12.5.1. when I first built this app successfully, when you go to a buttons attribute inspector, there is no property for "style", there is "state config" and "title". And by default "state config" is "Default". And this works fine. But now when I tried rebuilding this Apple Pie app on Xcode 13.2.1, they added a new parameter for a button in the attribute inspector, which is the "Style" parameter, and the default for this is "Plain", which sets the "state config" parameter to "plain". This is what causes the crash. The "state config" parameter must be set to "Default", and you do that by changing the "style" parameter to "Default". At first it will be set to "plain", you have to change it to "Default".

IOS 15 update seems to have changed some button behavior. use sender.titleLable!.text! instead of sender.title(for: normal)! sender.configuration!.text! also works. Also changing the button style from plain to default. It is better here to use a guard.

Interface builder not setting button title?
 
 
Q