View modifier for a custom hover effect in SwiftUI
In this article we will look into how to create a custom hover effect in SwiftUI and how to abstract this logic into a reusable view modifier.
As an example we'll take a tappable view that gets a pink background on hover. To detect if the user is hovering over a view, we can use onHover(perform:) method. We will save the current isHovered
value into @State
variable and use this variable to control the view's background.
struct EditView: View {
@State private var isHovered = false
var body: some View {
Text("Edit")
.padding()
.onTapGesture {
// some action
}
.background(isHovered ? Color.pink : Color.clear)
.clipShape(
RoundedRectangle(
cornerRadius: 10,
style: .continuous
)
)
.onHover { isHovered in
withAnimation {
self.isHovered = isHovered
}
}
}
}
If we have multiple views in our app that get pink background on hover, then we need to repeat this logic for all of them. It would be nicer to create a ViewModifier that holds all of this logic and can be applied to any of our views.
struct PinkBackgroundOnHover: ViewModifier {
@State private var isHovered = false
func body(content: Content) -> some View {
content
.background(isHovered ? Color.pink : Color.clear)
.clipShape(
RoundedRectangle(
cornerRadius: 10,
style: .continuous
)
)
.onHover { isHovered in
withAnimation {
self.isHovered = isHovered
}
}
}
}
extension View {
func pinkBackgroundOnHover() -> some View {
self.modifier(PinkBackgroundOnHover())
}
}
Now we can just add our pinkBackgroundOnHover()
modifier to any view in the app.
struct EditView: View {
var body: some View {
Text("Edit")
.padding()
.onTapGesture {
// some action
}
.pinkBackgroundOnHover()
}
}
You can get the example code for this article from our GitHub.