View modifiers are a way to customize and enhance the appearance and behavior of SwiftUI views. They can be applied to any view or another view modifier, producing a different version of the original value.
For example, you can use view modifiers to change the font, color, padding, alignment, animation, and more of a view.
Text("Hello, world!")
.font(.title)
.foregroundColor(.white)
.padding()
.background(Color.blue)
.cornerRadius(10)
You can also create your own custom view modifiers by adopting the ViewModifier protocol and implementing the body(content:)
method. The content parameter is the original view that the modifier is applied to, and the return value is the modified view.
To use this custom view modifier, you can either call the modifier(_:)
method on any view and pass an instance of your custom view modifier, or you can create an extension on the View protocol and add a custom method that applies your modifier.
import SwiftUI
struct PinkBorder: ViewModifier {
var radius: Double
func body(content: Content) -> some View {
content
.clipShape(RoundedRectangle(cornerRadius: radius))
.overlay {
RoundedRectangle(cornerRadius: radius)
.stroke(.pink, lineWidth: 1.0)
}
}
}
extension View {
func pinkBorder(radius: Double = 0) -> some View {
modifier(PinkBorder(radius: radius))
}
}
struct ContentView: View {
var body: some View {
VStack {
Image("avatar")
.resizable()
.aspectRatio(contentMode: .fit)
.foregroundStyle(.tint)
.frame(width: 100, height: 100)
.pinkBorder(radius: 20)
}
.padding()
}
}
You can also add parameters to your custom view modifier to make it more flexible and customizable. For example, you can add a color and a width parameter to your RedBorderAndShadow modifier and use them to set the border color and width:
struct RedBorderAndShadow: ViewModifier {
let color: Color
let width: CGFloat
func body(content: Content) -> some View {
content
.border(color, width: width)
.shadow(radius: 10)
}
}
extension View {
func redBorderAndShadow(color: Color = .red, width: CGFloat = 2) -> some View {
modifier(RedBorderAndShadow(color: color, width: width))
}
}
struct ContentView: View {
var body: some View {
VStack {
Text("Hello, world!")
.redBorderAndShadow(color: .green, width: 4)
}
.padding()
}
}