UIButton Configuration Tutorial: Getting Started
Learn how to give your buttons some style and color using the UIButton Configuration API. By Jordan Osterberg.
Sign up/Sign in
With a free Kodeco account you can download source code, track your progress, bookmark, personalise your learner profile and more!
Create accountAlready a member of Kodeco? Sign in
Sign up/Sign in
With a free Kodeco account you can download source code, track your progress, bookmark, personalise your learner profile and more!
Create accountAlready a member of Kodeco? Sign in
Sign up/Sign in
With a free Kodeco account you can download source code, track your progress, bookmark, personalise your learner profile and more!
Create accountAlready a member of Kodeco? Sign in
Contents
UIButton Configuration Tutorial: Getting Started
15 mins
- Getting Started
- Beginning Adoption of UIButton.Configuration
- Styling Options for Buttons
- Adding Images
- Introducing the Configuration Update Handler
- Styling the Get Help Button
- Creating Toggle Buttons
- Creating Pop-Up Buttons
- Changing the Button’s Title
- Styling the Checkout Button
- Where to Go From Here?
Styling the Get Help Button
Find the helpButton property. At the top of the initialization closure add the following code:
var config = UIButton.Configuration.tinted()
config.buttonSize = .large
config.cornerStyle = .medium
Then once again set the configuration right before the return statement like so:
button.configuration = config
Build and run.

Excellent! Now, you’ll learn about how to create toggle buttons.
Creating Toggle Buttons
A wonderful use case of configurationUpdateHandler is that of toggle buttons.
Using the update handler, you can change a button’s icon based on its current state.
Build and run the app. The first screen you see if the BookListViewController.

Notice on each of the book cells, there’s a button for adding them to the cart, located on the trailing edge.
If you tap on one, the text changes from “Add” to “Remove”. While this isn’t a bad user experience, implementing the new button configuration API will make it much better.
First, open BookCollectionCell.swift.
Next, locate the addToCartButton property. At the top of its initializer closure add the following code:
var config = UIButton.Configuration.gray()
This sets up a new configuration object from the gray template this time.
Then, set a default image for the button using the cart.badge.plus SF Symbol:
config.image = UIImage(systemName: "cart.badge.plus")
As you’ve done a few times now, set the button’s configuration right before the return statement:
button.configuration = config
Great job! Now, build and run.
![]()
The icon appears correctly, however, the title feels unnecessary, and the icon doesn’t change when a book is added to the cart. You’ll fix this now.
Replace this line of code, which sets the button’s title:
button.setTitle("Add", for: .normal)
With configurationUpdateHandler:
button.configurationUpdateHandler = { [unowned self] button in
// 1
var config = button.configuration
// 2
let symbolName = self.isBookInCart ? "cart.badge.minus" : "cart.badge.plus"
config?.image = UIImage(systemName: symbolName)
// 3
button.configuration = config
}
Here’s what happens in the code above:
- As you did earlier, grab a mutable copy of the button’s current configuration.
- Modify
config‘simageproperty based on theisBookInCartof theBookCollectionCellclass. - Finally, update the button’s configuration.
Once again we need to tell the button to update its configuration at the right time. In this case it is when isBookInCart changes.
Find the isBookInCart property. Then change the contents of the didSet handler with the following code:
addToCartButton.setNeedsUpdateConfiguration()
Build and run.
![]()
It works perfectly! The image changes to reflect whether the book is in the user’s cart.
Now it’s time to check out!
Creating Pop-Up Buttons
Tap the cart button in the navigation bar and gaze upon the unstyled buttons.

Additionally, if you change the shipping speed, there’s no indication of the current shipping selection.
Oh, the horror! Fortunately, you have the tools to fix this up in a jiffy!
To get started, you’ll style the shipping speed button and configure it so the current shipping speed appears on the label.
Open CartPanelView.swift.
First, locate the shippingSpeedButton property. Next, at the top of the initializer closure add the following code:
var config = UIButton.Configuration.tinted()
config.buttonSize = .medium
config.cornerStyle = .medium
config.titleTextAttributesTransformer =
UIConfigurationTextAttributesTransformer { incoming in
var outgoing = incoming
outgoing.font = UIFont.preferredFont(forTextStyle: .headline)
return outgoing
}
This creates a tinted configuration and sets its size and corner style. Then creates a title text transformer to set the button’s font.
Once again add the following code right before the return statement:
button.configuration = config
Build and run, and you’ll see the new styling applied to the shipping speed button.

However, selecting a shipping speed still doesn’t change the button’s title. You fix this next.
Changing the Button’s Title
Changing the title is an extremely easy job using the new changesSelectionAsPrimaryAction on UIButton!
This button uses the menu property to set a menu that pops up when the button is tapped. The new changesSelectionAsPrimaryAction property allows you to tell UIKit that it should use the selection from the menu as the title of the button.
Add the following code right after button.showsMenuAsPrimaryAction = true:
button.changesSelectionAsPrimaryAction = true
Now, build and run, and change the shipping speed in the cart view:

Awesome! There’s now an easy way to view and change the shipping speed of the order.
All that’s left is to make the checkout button styled, and then the app will be complete!
Styling the Checkout Button
Locate the checkoutButton property, and at the top of the initializer closure, create a basic configuration for it like you’ve done several times now:
var config = UIButton.Configuration.filled()
config.buttonSize = .large
config.cornerStyle = .medium
config.imagePlacement = .leading
config.imagePadding = 5
config.titleTextAttributesTransformer = UIConfigurationTextAttributesTransformer { incoming in
var outgoing = incoming
outgoing.font = UIFont.preferredFont(forTextStyle: .headline)
return outgoing
}
You should be aware by now of what’s happening here!
When you’re done, the checkout button will display an activity indicator as the order is placed. The image properties you set above will control its placement and padding between the title.
And once again add the following code right before the return statement:
button.configuration = config
Almost done! Add a configurationUpdateHandler to update the button style when state changes:
button.configurationUpdateHandler = { [unowned self] button in
// 1
var config = button.configuration
// 2
config?.showsActivityIndicator = self.checkingOut
// 3
config?.title = self.checkingOut ? "Checking Out..." : "Checkout"
// 4
button.isEnabled = !self.checkingOut
// 5
button.configuration = config
}
Here’s what’s is happening:
- Store
button‘sconfigurationin a mutable variable. - Show the activity indicator when the user is checking out (based on the
checkingOutproperty of the class). - Change the title based on whether or not the user is checking out.
- Additionally, disable the button when checking out.
- Finally, save the changes to the configuration.
The last step is to make the usual call to setNeedsUpdateConfiguration when the state changes.
Find the checkingOut property. Replace the contents of the didSet block with the following code:
checkoutButton.setNeedsUpdateConfiguration()
Excellent! Build and run, and navigate to the cart.

When you tap the checkout button, it displays the activity indicator for a second before reverting back to its previous state.
The app is complete, and you’re now a button enthusiast!