SwiftUI provides a wide range of built-in modifiers to customize the appearance and behavior of your views. However, in many cases, you may want to encapsulate certain modifications to reuse them across multiple views. This is where custom modifiers come into play. By creating custom modifiers, you can define reusable and consistent styling or behavior for your SwiftUI views, making your code cleaner and more maintainable.
SwiftUI allows you to create your own custom modifiers by conforming to the ViewModifier
protocol. This protocol requires you to define how your custom modifier should modify the original view.
Basic Custom Modifier Example
To implement ViewModifier
protocol you just need to add the function body(content: Content)
, being content
the view that the modifier is going to be applied.
struct BadgeModifier: ViewModifier {
func body(content: Content) -> some View {
ZStack(alignment: .topTrailing) {
content
Circle()
.fill(.red)
.frame(width: 16, height: 16)
.offset(x: 4, y: -4)
}
}
}
Image(systemName: "bell")
.resizable()
.frame(width: 32, height: 32)
.modifier(BadgeModifier())
We can simplify this adding a view extension
.
extension View {
func badge() -> some View {
self.modifier(BadgeModifier())
}
}
Image(systemName: "bell")
.resizable()
.frame(width: 32, height: 32)
.badge()
Adding Parameters to Custom Modifiers
Custom modifiers can also accept parameters, giving you flexibility to adjust behavior based on different views or user input. Let's modify our previous example by adding a parameter to add a number to our badget:
struct BadgeModifier: ViewModifier {
let number: String
func body(content: Content) -> some View {
ZStack(alignment: .topTrailing) {
content
Text(number)
.foregroundStyle(.white)
.font(.subheadline)
.padding(.horizontal, 4)
.background(.red)
.cornerRadius(99) // High value makes a circle
.offset(x: 4, y: -4)
}
}
}
We add the parameter to our extension as well.
extension View {
func badge(number: String) -> some View {
self.modifier(BadgeModifier(number: number))
}
}
Then we can set a number to our badge with a parameter:
Image(systemName: "bell")
.resizable()
.frame(width: 32, height: 32)
.badge(number: "2")
Be the first to comment