There are questions with the same title on StackOverflow but they have nothing to do with what I am asking.
I have this highlight style for a button.
struct HighlightableButtonStyle<N, H>: ButtonStyle where N: View, H: View {
private let alignment: Alignment
private let normal: () -> N
private let highlighted: () -> H
init(alignment: Alignment = .center,
@ViewBuilder normal: @escaping () -> N,
@ViewBuilder highlighted: @escaping () -> H) {
self.alignment = alignment
self.normal = normal
self.highlighted = highlighted
}
func makeBody(configuration: Configuration) -> some View {
configuration.label
.frame(maxWidth: .infinity, maxHeight: .infinity)
.contentShape(Rectangle())
.background(alignment: alignment, content: {
configuration.isPressed ? Color.red : Color.blue //1
})
}
}
My problem is with the line marked with //1
.
If the line is at is is, it compiles fine, but I would like to pass colors to the style, so I change that line to
configuration.isPressed ? highlighted : normal
and I get this error
Result values in '? :' expression have mismatching types '() -> H' and '() -> N'
Insert ' as! () -> N'
Type '() -> N' cannot conform to 'View'
The most intriguing is the last line. How can N not conform to view?
What am I missing?
>Solution :
highlighted
and normal
are functions. You should call them (by adding ()
at the end) to make them produce a View
.
if configuration.isPressed {
highlighted()
} else {
normal()
}
Note that you cannot use the ternary operator here because highlighted
and normal
return different types – H
and N
respectively.