NEW BOOK! Swift Gems: 100+ tips to take your Swift code to the next level. Learn more ...NEW BOOK! Swift Gems:100+ advanced Swift tips. Learn more...

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.

Swift Gems by Natalia Panferova book coverSwift Gems by Natalia Panferova book cover

Check out our new book!

Swift Gems

100+ tips to take your Swift code to the next level

Swift Gems

100+ tips to take your Swift code to the next level

  • Advanced Swift techniques for experienced developers bypassing basic tutorials
  • Curated, actionable tips ready for immediate integration into any Swift project
  • Strategies to improve code quality, structure, and performance across all platforms
  • Practical Swift insights from years of development, applicable from iOS to server-side Swift