Now that we have the basics in place, we can start to make it interesting.
We can start with the most simple features of the buttons in the design system, and work down through the levels of complexity and customisation. So to start, let’s deal with the colors.
In the design system above, we’ve got 3 main colors:
- Default buttons — using our main brand color, blue.
- Accent buttons, which use our secondary brand color, a pale green.
- Error buttons, which are a light red
We can create these options in a MyButtonColor
enum to handle this cleanly:
public struct MyButton: View {public enum MyButtonColor {
case `default`
case accent
case error
var mainColor: Color {
switch self {
case .`default`: return .blue
case .accent: return .green.opacity(0.85)
case .error: return .red.opacity(0.6)
}
}
var detailColor: Color {
switch self {
case .`default`: return .white
case .accent: return .white
case .error: return .white
}
}
}
// ...
}
Here, we’re harnessing the astonishing power of Swift’s enumerations — when we add computed properties like mainColor
and detailColor
to the enum, your case switches over self
and finds the value defined for itself!
Quick explainer: Since default
is a Swift keyword, we need to ‘escape’ it with back-ticks if we want to call one of our enum cases default
, or the compiler will get confused.
Now we can modify our MyButton
’s body
property to include these color properties when drawing:
public var body: some View {
Button(action: action, label: {
buttonWithColor
})
}private var buttonWithColor: some View {
Text(title)
.foregroundColor(type.detailColor)
.background(
Capsule()
.fill(type.mainColor)
)
}
Now, finally, we can modify the initialiser of MyButton
to expose this type as an argument. Since our .default
button color is the most commonly used, we should use it as the default argument for color
in this initialiser:
private let color: MyButtonColor
private let title: String
private let action: () -> Voidpublic init(color: MyButtonColor = .`default`,
title: String,
action: @escaping () -> Void) {
self.color = color
self.title = title
self.action = action
}
Now, your team can use MyButton
the exact same way it uses a default SwiftUI Button
and draw our .default
(blue) button. Our team can also use the more complex version of the initialiser when they want to override the default colour for the .accent
(green) or .error
(red) variants.
Credit goes to the respective owner!