I'm trying to make multiple Text
views' .overlay (RoundedRectangle)
change colours on mouse hovering. Each Text
view needs to do so individually, though they all have the same behaviour ( the .overlay
turns purple ). My code is based on @twostraws
's https://www.hackingwithswift.com/quick-start/swiftui/how-to-detect-the-user-hovering-over-a-view , which uses .onHover
and @State private var
:
It works, but unfortunately there are many blocks of identical code ( the only difference is the name of the @State private var
- overText#
)
import SwiftUI
struct myStyleEnglish: ViewModifier {
func body(content: Content) -> some View {
content
.padding(10)
.foregroundStyle(.cyan.opacity(0.8))
.font(.custom("Georgia", size: 14))
}
}
struct myStyleFrench: ViewModifier {
func body(content: Content) -> some View {
content
.padding(10)
.foregroundStyle(.pink.opacity(0.8))
.font(.custom("Futura", size: 14))
}
}
struct ContentView: View {
@State private var overText1 = false
@State private var overText2 = false
@State private var overText3 = false
@State private var overText4 = false
// Many more @State lines π
var body: some View {
VStack(spacing: 10) {
Text("π£οΈ LET'S LEARN FRENCH ! π£οΈ")
.modifier(myStyleEnglish())
HStack(spacing: 10) {
Text("CALL THE FIRE DEPARTMENT !")
.modifier(myStyleEnglish())
Text("APPELEZ LES POMPIERS !")
.modifier(myStyleFrench())
.overlay(
RoundedRectangle(cornerRadius: 10)
.stroke(overText1 ? .purple.opacity(0.8) : .white.opacity(0.1))
)
.onHover { over in overText1 = over }
}
HStack(spacing: 10) {
Text("CALL THE AMBULANCE !")
.modifier(myStyleEnglish())
Text("APPELER L'AMBULANCE !")
.modifier(myStyleFrench())
.overlay(
RoundedRectangle(cornerRadius: 10)
.stroke(overText2 ? .purple.opacity(0.8) : .white.opacity(0.1))
)
.onHover { over in overText2 = over }
}
HStack(spacing: 10) {
Text("CALL THE POLICE !")
.modifier(myStyleEnglish())
Text("APPELEZ LA POLICE !")
.modifier(myStyleFrench())
.overlay(
RoundedRectangle(cornerRadius: 10)
.stroke(overText3 ? .purple.opacity(0.8) : .white.opacity(0.1))
)
.onHover { over in overText3 = over }
}
HStack(spacing: 10) {
Text("CALL CARETAKER !")
.modifier(myStyleEnglish())
Text("APPELEZ LE GARDIEN !")
.modifier(myStyleFrench())
.overlay(
RoundedRectangle(cornerRadius: 10)
.stroke(overText4 ? .purple.opacity(0.8) : .white.opacity(0.1))
)
.onHover { over in overText4 = over }
}
// Many more HStacks π°
}
}
}
#Preview {
ContentView()
}
I am already using ViewModifier
to reduce repeating codes, but Swift will not allow me to put the .onHover
+ .overlay
+ @State
inside the ViewModifier
:
import SwiftUI
struct myStyleEnglish: ViewModifier {
func body(content: Content) -> some View {
content
.padding(10)
.foregroundStyle(.cyan.opacity(0.8))
.font(.custom("Georgia", size: 14))
}
}
struct myStyleFrench: ViewModifier {
func body(content: Content) -> some View {
content
.padding(10)
.foregroundStyle(.pink.opacity(0.8))
.font(.custom("Futura", size: 14))
// ππππππππ Swift does not allow this ππππππππ
@State private var overTextgeneral = false
.overlay(
RoundedRectangle(cornerRadius: 10)
.stroke(overTextgeneral ? .purple.opacity(0.8) : .white.opacity(0.1))
)
.onHover { over in overTextgeneral = over }
// ππππππππ Swift does not allow this ππππππππ
}
}
struct ContentView: View {
var body: some View {
VStack(spacing: 10) {
Text("π£οΈ LET'S LEARN FRENCH ! π£οΈ")
.modifier(myStyleEnglish())
HStack(spacing: 10) {
Text("CALL THE FIRE DEPARTMENT !")
.modifier(myStyleEnglish())
Text("APPELEZ LES POMPIERS !")
.modifier(myStyleFrench())
}
HStack(spacing: 10) {
Text("CALL THE AMBULANCE !")
.modifier(myStyleEnglish())
Text("APPELER L'AMBULANCE !")
.modifier(myStyleFrench())
}
HStack(spacing: 10) {
Text("CALL THE POLICE !")
.modifier(myStyleEnglish())
Text("APPELEZ LA POLICE !")
.modifier(myStyleFrench())
}
HStack(spacing: 10) {
Text("CALL CARETAKER !")
.modifier(myStyleEnglish())
Text("APPELEZ LE GARDIEN !")
.modifier(myStyleFrench())
}
// Many more HStacks π°
}
}
}
#Preview {
ContentView()
}
Maybe the issue is that this .onHover
method uses separate @State
variables for separate implementations? Is there a way to apply the .onHover
modifer to multiple Text
views - for example inside a ViewModifier
- so multiiple Text
views have the same behaviour , but each will operate individually ( each has its .overlay
independently turn purple on mouse hover ) ?
Thank you.