I'm trying to create a ButtonStyle
. I want to let the background color be buttonBackgroundHover
color which is already created in Assets.xcassets
, and other time remains the default background color (same as the background color of the window). So I tried the code below, but Xcode said an error: Member 'background(ignoresSafeAreaEdges:)' expects argument of type 'Color'
struct PlayerButton: ButtonStyle {
@State private var isOnHover: Bool = false
func makeBody(configuration: Configuration) -> some View {
configuration.label
.background(isOnHover ? Color("buttonBackgroundHover") : .background)
}
}
But if I replace .background(isOnHover ? Color("buttonBackgroundHover") : .background)
with .background(.background)
, there's no argue. I wonder what's wrong with that and how can I solve this problem. I would appreciate your help.
CodePudding user response:
The background
method is declared like this:
func background<S>(_ style: S, ignoresSafeAreaEdges edges: Edge.Set = .all) -> some View where S : ShapeStyle
Notice that the argument it takes is of type S
where S : ShapeStyle
. When you do .background(.red)
or .background(.background)
, S
is Color
or BackgroundStyle
respectively.
However, when you pass in:
isOnHover ? Color("buttonBackgroundHover") : .background
There is no single type S
that works. You want S
to be either Color
or BackgroundStyle
, but the type of the above expression can only be one type of those types. The compiler sees that since Color("buttonBackgroundHover")
is of type Color
, it mistakenly thinks that you want the third operand .background
to be of type Color
too. But there is no such property as Color.background
, but since Color
is a view, it has a background
method too, and that is what .background
gets resolved to. It expects a Color
argument, because you are calling an instance method without an instance (Color.background
).
Anyway, there is a type eraser for ShapeStyle
- AnyShapeStyle
. Apply that to make both branches of the conditional expression the same type:
.background(isOnHover ? AnyShapeStyle(Color("buttonBackgroundHover")) : AnyShapeStyle(.background))
CodePudding user response:
There is no color Color.background
- it tries to apply same .background()
modifier, but there is Color first in ternary operator, so types conflict - error.
I assume it was expected
.background(isOnHover ? Color("buttonBackgroundHover") :
Color(uiColor: UIColor.systemBackground)) // << this !!