在我的应用中,我有各种按钮。它们有许多共同的特点,但颜色不同。我试图编写一个包含每个按钮样式的类,明确指出它们唯一的不同之处是颜色。
问题是我还想对其中一个使用 .tint。但那是一个ShapeStyle
而不是一个 Color。
struct CommonButtonStyle: ButtonStyle {
@Environment(\.isEnabled) var isEnabled: Bool
@Environment(\.isFocused) var isFocused: Bool
var labelColor: Color
var enabledColor: some ShapeStyle
var pressedColor: Color
func makeBody(configuration: Configuration) -> some View {
configuration.label
.font(.system(size: 14, weight: .bold))
.padding(.horizontal, 16)
.padding(.vertical, 10)
.foregroundStyle(labelColor)
.frame(maxHeight: 40)
.background((isEnabled && configuration.isPressed) ? pressedColor : enabledColor)
.clipShape(Capsule())
.containerShape(Capsule())
.opacity(isEnabled ? 1 : 0.5)
.focusable()
}
}
这里的问题是不匹配的返回类型和声明,var enabledColor: some ShapeStyle
因为编译器抱怨Property declares an opaque return type, but has no initializer expression from which to infer an underlying type
有没有办法让我得到这个变量来存储一个Color
或一个,ShapeStyle
以便我可以做
CommonButtonStyle(labelColor: .black, enabledColor: .tint, pressedColor: .white)
和
CommonButtonStyle(labelColor: .black, enabledColor: .blue, pressedColor: .white)
这是不允许的。因为
.background
其内容为ShapeStyle
或View
,而不是两者。您可以做一个小实验来检查它,例如:因此,在这种情况下,
.background
根本行不通。它不能接受两种不同的类型作为其内容。您必须找到一种解决方案以.background
某种方式将其拆分为两个。感谢@Mojitaba 提供的解决方案。
从现在开始,您可以执行
if
如下条件:输出:
使用三元运算符切换背景样式不起作用,因为类型不匹配。
但是,您可以改用
background(alignment:content:)
if-else 开关。此修饰符采用闭包,即ViewBuilder
。其他要点:
要将 传递
ShapeStyle
给您的自定义ButtonStyle
,需要将自定义样式转变为通用样式。除了应用之外
.clipShape(Capsule())
,您还可以使用Capsule
作为背景填充的形状。您的两个示例现在可以编译并运行: