SwiftUI: Reusable UI with Custom Modifiers

Nemi Shah
3 min readDec 8, 2022

The ability to create custom view modifiers is a powerful feature in SwiftUI, in this article we will cover examples of how this feature can be used to make building UI so much easier. If you are not familiar with ViewModifiers in SwiftUI and how to create custom ones, you can read about it here

The goal with this article is to cover some of the different ways to create custom modifiers and styles in SwiftUI and how they can be used to make building UI more declarative while still achieving a clean and consistent final output. The final UI we want to build is:

Let’s consider all the individual components on the screen:

  • Image: A standard image component with some corner radius
  • Texts: We have a title and a body text
  • Button: A full width button

Plain SwiftUI code

If you build this screen without any modifiers, the code would look something like this:

struct ContentView: View {
var body: some View {
VStack (alignment: .leading) {
Image("feature")
.resizable()
.aspectRatio(contentMode: .fill)
.frame(minWidth: 0, maxWidth: .infinity)
.frame(height: 220)
.cornerRadius(12)
.padding(.bottom, 12)

Text("Custom ViewModifiers in SwiftUI are the best!")
.foregroundColor(Color("titleTextColor"))
.font(.system(size: 20, weight: .bold))
.padding(.bottom, 12)

Text("Custom ViewModifiers in SwiftUI let you create resuable styles that can be applied to all your views")
.foregroundColor(Color("bodyTextColor"))
.font(.system(size: 14, weight: .medium))


Spacer()
Button(action: {

}) {
Text("Label")
.font(.system(size: 14, weight: .medium))
}
.frame(minWidth: 0, maxWidth: .infinity)
.padding(.horizontal, 10)
.padding(.vertical, 12)
.background(Color.blue)
.foregroundColor(Color.white)
.cornerRadius(12)
}
.padding(.all, 16)
}
}

There are a couple problems with this approach:

  • Styling for some of the elements (the title and details texts for example) would have to be duplicated
  • Changes to some of the common styling (element padding, corner radius etc) would have to be made in multiple places

Now you could solve this problem the UIKit way by creating custom views, but personally Im not a fan of this approach because it involved moving away from the built in Views and makes onboarding new team members more frictional. An easier way would be to define some universal view modifiers that can be applied instead of the styles themselves.

Lets break down the common styling we need:

  • Screen container: The screen itself has a universal padding, this is optional but I prefer having all screens have a universal style
  • Corner radius
  • Title and body texts
  • Full width: Items need to be able to fill the width of their parent (the button and the image in the above example)
  • Button styling
  • Image scaling

This blog has been moved to my own site

You can read the full article for free here: https://nemishah.com/blog/swiftui-reusable-ui-with-custom-modifiers

--

--