When creating views in SwiftUI you will almost certainly use View Modifiers to adjust how a view looks from its font, to border, to colours, and so on. It is not uncommon to have serveral modifiers applied to each item in the view to get the look that you desire.
SwiftUI provides a way to group these modifiers together so that you can apply them as a group. There are a few benefits to this:
First, it cleans up the code in your view because you can have just a single custom modifier applied and keep all of the details encapsulated elsewhere in the code.
Second, it allows you to reuse the same group of modifiers elsewhere in the app so that you can keep your code DRY (don’t repeat yourself). A change in the custom modifier would affect all views that use the custom modifier.
In this tutorial we’ll look at how we can create our own custom modifier and how this can be applied to a view.
First step is to create the custom modifier. We do this as follows:
struct CustomTextModifier: ViewModifier {
func body(content: Content) -> some View {
content
.padding()
.background(Color.white)
.cornerRadius(10)
.shadow(radius: 5)
}
}
We create a struct on line 1 and call it CustomTextModifier that conforms to the ViewModifier protocol.
The ViewModifier requires the body to be implemented that gets the current body of the caller. It requires “some” View which is likely familiar to you, but in short, it doens’t mind what body is returned as long as the body conforms to the View protocol.
Below that we return content, which is the current body of the caller, along with the modifiers attached. We do not need to specify the return keyword because Swift knows that some View needs to be returned, and because content is a View, and is the last expression (indeed, the only expression here), Swift knows that it needs to be returned.
Thats all. In short, we comply to the ViewModifier that requires the body be implemented. content: Content is the body of the caller (the view that will use this modifier). We return back the content with the modifiers applied.
Lets take a look at how to use this. One way to do that is as follows:
struct ContentView: View {
var body: some View {
Text("Hello, DevFright!")
.modifier(CustomTextModifier())
}
}
}
On our SwiftUI view, we use a Text view that contains the text “Hello, DevFright!”.
On line 4, we use .modifier(CustomTextModifier()) to apply the four modifiers from the example above.
We have now managed to use all four modifier with a single custom modifier. However, the syntax is different to that of a normal view modifier. Lets add in an extension to simplify this a little.
extension View {
func textModifier() -> some View {
self.modifier(CustomTextModifier())
}
}
We can add an extension to View and add in our custom modifier. On line 2 we call it textModifier in this example. Call it whatever you want that makes sense in the context of your code.
On line 3 we call self.modifier(CustomTextModifier()) that is a view, so returns just fine.
...
var body: some View {
Text("Hello, DevFright!")
.textModifier()
...
By adding in the extension, we can now use the custom modifier by just applying .textModifier() which makes it simpler to implement as well as following the same pattern as other modifiers.
Overall, custom modifiers are a great way to simplify the view logic and encapsulate long lists of modifiers to make the view code more readable and maintainable.
Leave a Reply
You must be logged in to post a comment.