SwiftUI Styles using Viewbuilders

Last modified: Sep 5th, 2020

Using the ability to extend the View class in Swift we can add custom styles to our components. As an example this allows you to create different levels of shadow:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
enum ShadowClass {
    case xs
    case sm
    case md
}

extension View {
    @ViewBuilder
    func shadow(_ level: ShadowClass) -> some View {
        switch (level) {
        case .xs:
            self.shadow(color: Color.black.opacity(0.05), radius: 1, x: 0, y: 1)
        case .sm:
            self.shadow(color: Color.black.opacity(0.05), radius: 2, x: 0, y: 1)
        case .md:
            // We can even define multiple shadows to create a specific effect.
            self
                .shadow(color: Color.black.opacity(0.10), radius: 3, x: 0, y: 1)
                .shadow(color: Color.black.opacity(0.06), radius: 2, x: 0, y: 1)
        }
    }
}

By extending View we are able to call .shadow on all subclasses of View, which all our components are. This allows us to define a strict set of shadows that we can use for all our components and that we can edit in one place.

struct ViewWithShadow: View {
    var body: some View {
        HStack {
            Text("This view has some shadow")
        }
        .padding()
        .cornerRadius(8)
        .shadow(.md)
    }
}

If you like my work you can reach out to me on twitter (@nickbelzer) or buy me a coffee. You can find the source code for both the site and it's content on Github.