SwiftUI: What are ViewModifiers?

SwiftUI: What are ViewModifiers?

·

3 min read

SwiftUI is quickly becoming the popular choice for making iOS apps, and one of the most common things you use is ViewModifiers. If you have worked with SwiftUI before reading this and don’t know what ViewModifiers are, I guarantee you have used them before without realising it.

ViewModifiers are methods you call on the Views you use in your app to customise their appearance and behaviour. You use them to change colours and sizes, add gestures, add accessibility options etc to your Views, if you have ever used .background or .foregroundColor in your project, these are examples of ViewModifiers.

How do you use ViewModifiers?

Let’s start by creating a project, I won't bore you with the whole process so just make sure to select SwiftUI instead of Storyboard when making your project.

The default View created for you already uses some modifiers so let's take a look at that:

struct ContentView: View {
    var body: some View {
        VStack {
            Image(systemName: "globe")
                .foregroundColor(.accentColor)
            Text("Hello, world!")
        }
        .padding()
    }
}

The View above uses .padding and .foregroundColor .

  • .padding : Let you specify the padding for your View, note that because we don't provide any values it applies the system default padding for all sides. You can specify the edges and values like this .padding(.top, 12) or .padding(.horizontal, 12) for example

  • .foregroundColor : Will set the foreground colour for the view, affecting text colours, tints etc

Some common examples of built-in modifiers are:

  • .frame : Used to change the size of a View

  • .font : Used to change the font family, size etc for a Text

Let's try making something ourselves, our target is to build a simple filled button:

Before we start let’s review the constraints we want to use on the button — Padding, Corner radius, and Background Color.

Let's start by adding a simple button with some text:

Button(action: {
    // On click
}) {
    Text("Label")
}

This will render a simple text button:

After adding our modifiers:

Button(action: {
    // On click
}) {
    Text("Label")
        .padding(.horizontal, 20)
        .padding(.vertical, 14)
        .foregroundColor(Color.white)
}
.background(Color.blue)
.cornerRadius(14)

Custom View Modifiers

The example above is very simple but if your project had many Views with similar styles (common padding values, themed background colours etc) it can get very annoying very quickly to have to repeat the same modifiers. Fortunately, SwiftUI lets you create your own custom modifiers.

Let's consider the example above if you notice the button text doesn’t exactly match what we were trying to build. Let's create a custom modifier for the button text:

struct ButtonTextModifier: ViewModifier {
    func body(content: Content) -> some View {
        content
            .font(.system(size: 17, weight: .semibold))
            .lineSpacing(22)
    }
}

And let's apply this modifier to our button and voila:

Text("Label")
  .padding(.horizontal, 20)
  .padding(.vertical, 14)
  .foregroundColor(Color.white)
  .modifier(ButtonTextModifier())

Now this way of using custom modifiers is perfectly fine, but personally, I’m not a fan of having to use .modifier every time I want to apply a custom modifier. I prefer to create an extension to make this more convenient:

extension View {
    func buttonText() -> some View {
        modifier(ButtonTextModifier())
    }
}

And then use it this way:

Text("Label")
  .padding(.horizontal, 20)
  .padding(.vertical, 14)
  .foregroundColor(Color.white)
  .buttonText()

And that's a wrap! While the examples we covered were rather simple, ViewModifiers are extremely useful and the ability to make custom modifiers really makes them so much more powerful when building apps.