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 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 a 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 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 from our GitHub.