Subtitled button in SwiftUI

Buttons in SwiftUI are represented with a Button type. Buttons are easy to create and can be customized either with directly providing a styled label or using a ButtonStyle protocol to define the visual appearance. Quite often we can find ourselves in a situation where we need a button which has a title and also a subtitle. In this blog post I am gonna show how to create a SubtitledButton which does exactly that. We’ll also use ButtonStyle protocol to change the appearance of the button. Using buttonStyle view modifier it is easy to change the appearance of the SubtitledButton as sometimes we want to present it in different ways. In the example below we can see two SubtitledButtons where one has a plain and second a custom appearance.

SwiftUI view with two buttons what have title and subtitle. The first button has no background and the second one has blue background with rounded corners.
A SwiftUI view with two SubtitledButtons with different styles.
struct ContentView: View {
var body: some View {
VStack(spacing: 32) {
Text("Hello, world!")
SubtitledButton(title: "First Title", subtitle: "First Subtitle", action: tapAction)
.buttonStyle(PlainButtonStyle())
SubtitledButton(title: "Second Title", subtitle: "Second Subtitle", action: tapAction)
.buttonStyle(RoundedRowButtonStyle())
}.padding()
}
func tapAction() {
print("tapped")
}
}

Let’s now take a look at the SubtitledButton. It is a SwiftUI view which just incorporates a SwiftUI button with two Text values. The first Text represents the title and the second Text represents the subtitle. The title font can be changed by applying a font view modifier on the SubtitledButton. In the example below, the subtitle font is currently not configurable, although we could add another argument if needed. As the subtitle already has font view modifier applied then setting a font modifier on the whole button it does not override it.

struct SubtitledButton: View {
let title: LocalizedStringKey
let subtitle: LocalizedStringKey
let action: () -> Void
var body: some View {
Button(action: action, label: {
VStack(spacing: 4) {
Text(title)
Text(subtitle).font(.footnote)
}
})
}
}

ButtonStyle is a protocol in SwiftUI which is used for custom button appearances. In the makeBody function we can apply view modifiers to the label where the label is a view created when the Button was created.

struct RoundedRowButtonStyle: ButtonStyle {
@ViewBuilder func makeBody(configuration: Self.Configuration) -> some View {
configuration.label
.frame(maxWidth: .infinity)
.padding(8)
.background(Color.accentColor)
.cornerRadius(8)
.foregroundColor(.white)
}
}

Example Project

SwiftUISubtitledButton (Xcode 12.5)

If this was helpful, please let me know on Twitter @toomasvahter. Feel free to subscribe to RSS feed. Thank you for reading.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s