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?
Buttons are a staple of all apps, big and small.
In this tutorial, you’ll learn how to take your app’s buttons to the next level using the UIButton
Configuration API introduced in iOS 15. This API provides a flexible way to declare the style of buttons and have that style change when the state changes.
More specifically, you’ll learn how to do the following with the UIButton
Configuration API:
- Style buttons with ease.
- Add images and SF Symbols to buttons.
- Show a spinner on a button.
- Update a button’s configuration dynamically.
Read on to discover everything you need to know to start configuring buttons!
Getting Started
Download the starter project by clicking the Download Materials button at the top or bottom of the tutorial.
A quick refresher: In iOS 14, Apple introduced the UIAction
API for UIButton
, which removed the need for the target-action pattern. Here’s a brief example of how to use this API:
button.addAction(
UIAction { _ in
print("You tapped the button!")
}
)
When tapping the button, the block will be called and the print statement will execute.
If you’ve used a completion handler-based API before, this new UIAction
API should feel familiar.
Now you’ll learn how to use the Configuration API to take your button’s styles to the next level with ease.
Beginning Adoption of UIButton.Configuration
Build and run the starter project. Then tap on the person icon.
This opens the SignInViewController
view controller. As you can see, it looks quite bland. Fortunately, this is easy to fix with the new Configuration API!
At a high level, there are four primitive options for a button configuration. They come as four different functions on UIButton.Configuration
that generate a configuration object based on that template. The four options are as follows:
-
.plain
: A plain button with a transparent background. -
.filled
: A button whose background is filled with a color. -
.gray
: A button with a gray background. -
.tinted
: A button whose background is tinted with a color.
Styling Options for Buttons
To start styling buttons, open SignInViewController.swift, and find signInButton
.
At the top, inside the initializer closure, add the following code
var config = UIButton.Configuration.filled()
This created a basic configuration object based on the filled
template.
Once you have a configuration object, there are many options you can modify to create the perfect button!
For example, you can change the size of the button and the style of its corners. To do that, add the following code underneath the code you just added:
config.buttonSize = .large
config.cornerStyle = .medium
This sets the button size to large and the corner style to medium. You could have a play with the different options here later if you wish.
Another option on UIButton.Configuration
is titleTextAttributesTransformer
, which allows you to modify properties of the button’s title label.
Additionally, there’s a similar property, subtitleTextAttributesTransformer
, for modifying the button’s subtitle’s properties.
You’ll now set up a titleTextAttributesTransformer
to change the font of the “Sign In” button.
Add the following underneath the code you just added:
config.titleTextAttributesTransformer =
UIConfigurationTextAttributesTransformer { incoming in
// 1
var outgoing = incoming
// 2
outgoing.font = UIFont.preferredFont(forTextStyle: .headline)
// 3
return outgoing
}
Here’s what you’re doing inside the transformer block:
- Create a mutable reference to the
incoming
property namedoutgoing
so you can modify the attributes. - Set the font of the title on
outgoing
. - After that, return
outgoing
to apply the changes.
outgoing
and incoming
are AttributeContainer
types, which reflect several properties of UILabel
.
Now the button’s title will appear with the correct font once the configuration is applied.
Adding Images
Another great feature of the Configuration API is the ability to add images to your buttons.
You want to add a chevron icon to the end of the “Sign In” button.
Add the following code underneath the code you just added:
// 1
config.image = UIImage(systemName: "chevron.right")
// 2
config.imagePadding = 5
// 3
config.imagePlacement = .trailing
// 4
config.preferredSymbolConfigurationForImage
= UIImage.SymbolConfiguration(scale: .medium)
This code does the following:
- Initializes a
UIImage
with thechevron.right
SF Symbol. - Adds five points of padding between the title and the image.
- Places the image at the trailing end of the button.
- Sets the SF Symbol’s scale to
.medium
.
It’s almost time to test this new configuration on signInButton
!
The last thing to do is tell the button about the new config
object. At the end of the initializer, right before the return statement, add the following code:
button.configuration = config
Now, build and run.
Excellent! The button is looking beautiful with its new style :]
However… if you tap on the button, the new style makes the interaction feel a bit clunky:
To be clear: When you tap on the button, it’s hard to see that the sign-in request is processing. Wouldn’t it be great if the button style updated automatically when the sign-in is in progress?
Introducing the Configuration Update Handler
As it turns out, there is a way to update the button automatically when the state changes.
Introducing… configurationUpdateHandler
!
configurationUpdateHandler
is a closure called when the button’s configuration changes. You can use it to change the configuration based on your app’s state.
SignInViewController
has a Boolean property named signingIn
, which you’ll use inside configurationUpdateHandler
to change the button’s style.
Add the following code right before you set button.configuration
:
button.configurationUpdateHandler = { [unowned self] button in
// 1
var config = button.configuration
// 2
config?.showsActivityIndicator = self.signingIn
// 3
config?.imagePlacement = self.signingIn ? .leading : .trailing
// 4
config?.title = self.signingIn ? "Signing In..." : "Sign In"
// 5
button.isEnabled = !self.signingIn
// 6
button.configuration = config
}
Here’s what you’re doing in this code:
- First, grab a copy of the button’s
configuration
and store it in a variable so you can modify it. - Display the activity indicator if the user is signing in.
- The activity indicator’s position relative to the title is based on
imagePlacement
, so if the user is signing in, ensure it appears on the.leading
edge, and if they aren’t signing in, revert back to.trailing
to properly show the chevron. - Set the title to Signing In… when the user is signing in, and set it to Sign In when they aren’t.
- Disable the button if the user is signing in.
- Finally, update the button’s
configuration
so your changes are reflected.
As you saw, UIButton.Configuration
has a property named showsActivityIndicator
. When true
, the button’s image (regardless of whether it has one or not) will be replaced with an activity indicator.
The indicator’s position and padding relative to the title is based on imagePlacement
and imagePadding
.
The last thing to do is inform the button that the configuration needs to be updated whenever signingIn
changes.
Find the signingIn
property and replace the contents of the didSet
block with the following code:
signInButton.setNeedsUpdateConfiguration()
setNeedsUpdateConfiguration
informs the system that the button’s configuration needs to change.
Build and run.
Looking great!
Next, you can apply a similar style to another button.