英文:
Modify shape color inside custom ButtonStyle
问题
在我的项目中,我正在使用自定义形状作为按钮的标签。现在,我试图创建一个自定义的 ButtonStyle
,当按钮被按下时,可以改变自定义形状的颜色。
如果我要使用一个“普通”的按钮标签,比如 Text
,我可以这样做:
struct LightGrayButtonStyle: ButtonStyle {
func makeBody(configuration: Self.Configuration) -> some View {
configuration.label
.foregroundColor(configuration.isPressed ? .black : .red)
}
}
然而,configuration.label
并没有任何特定于 Shape
的视图修饰符,因此无法使用 .fill
等来改变颜色。
这是我的其余代码:
Button {
action()
} label: {
RingSegment() // 这是我的自定义形状
}
.buttonStyle(LightGrayButtonStyle()) // 我应用了自定义的按钮样式
如何在我的自定义 ButtonStyle
中更改自定义形状的颜色?或者,如何使我的自定义形状遵循我在 LightGrayButtonStyle
中实现的 makeBody
方法中可以设置的 foregroundColor
?
英文:
In my project, I am using my custom shape as a button's label. Now, I am trying to create a custom ButtonStyle
which changes the custom shape's color whenever a button is currently pressed.
If I were to use a "normal" Button label, e.g. a Text
, I could do this:
struct LightGrayButtonStyle: ButtonStyle {
func makeBody(configuration: Self.Configuration) -> some View {
configuration.label
.foregroundColor(configuration.isPressed ? .black : .red)
}
}
However, configuration.label
does not have any Shape
specific view modifiers, making it impossible to alter the color using .fill
for example.
This is the rest of my code:
Button {
action()
} label: {
RingSegment() // this is my custom shape
}
.buttonStyle(LightGrayButtonStyle()) // I apply my custom button style
How can I now change the color of my custom shape inside my custom ButtonStyle
? Alternatively, how can I make my custom shape respect the provided foregroundColor
which I can set inside the makeBody
method implemented by my LightGrayButtonStyle
?
答案1
得分: 1
你可以将所有的代码放在ButtonStyle
内部。
struct MyShapeButtonStyle<S: Shape>: ButtonStyle {
/// 自定义形状
let shape: S
/// 默认颜色
let color: Color
/// 使用任何形状
init(shape: S, color: Color) {
self.shape = shape
self.color = color
}
/// 默认是一个 `Circle`
init(color: Color) where S == Circle {
self.shape = Circle()
self.color = color
}
func makeBody(configuration: Self.Configuration) -> some View {
// 自定义形状
shape
// 形状的填充
.fill(configuration.isPressed ? .black : color) // 保持按钮内部能够放置标签
.overlay(content: {
// 保持自定义标签的能力
configuration.label
.foregroundColor(.white)
})
.foregroundColor(configuration.isPressed ? .black : color)
}
}
然后,你可以传入任何 Shape
和任何 Color
。
struct CustomButtonShapeView: View {
var body: some View {
VStack{
Button("Test") {
print("test")
}
.buttonStyle(MyShapeButtonStyle(color: .red))
Button("Test") {
print("test")
}
.buttonStyle(MyShapeButtonStyle(shape: Rectangle(), color: .blue))
}
}
}
这就是你的翻译结果。
英文:
You can move all the code inside the ButtonStyle
struct MyShapeButtonStyle<S: Shape>: ButtonStyle {
///Custom Shape
let shape: S
///Default Color
let color: Color
///Uses any Shape
init(shape: S, color: Color) {
self.shape = shape
self.color = color
}
///Default is a `Circle`
init(color: Color) where S == Circle {
self.shape = Circle()
self.color = color
}
func makeBody(configuration: Self.Configuration) -> some View {
//Custom shape
shape
//Fill for the shape
.fill(configuration.isPressed ? .black : color)//Keep the ability to put a label in the button
.overlay(content: {
//Keep the ability to have a custom label.
configuration.label
.foregroundColor(.white)
})
.foregroundColor(configuration.isPressed ? .black : color)
}
}
Then you can pass in any Shape
and any Color
.
struct CustomButtonShapeView: View {
var body: some View {
VStack{
Button("Test") {
print("test")
}
.buttonStyle(MyShapeButtonStyle(color: .red))
Button("Test") {
print("test")
}
.buttonStyle(MyShapeButtonStyle(shape: Rectangle(), color: .blue))
}
}
}
答案2
得分: 0
我选择的解决方案是在makeBody
函数内部应用foregroundColor
修饰符,并在填充自定义形状时使用该颜色。
这是我的代码:
// 声明按钮样式
struct LightGrayRingSegmentButtonStyle: ButtonStyle {
func makeBody(configuration: Self.Configuration) -> some View {
configuration.label
.foregroundColor(configuration.isPressed ? .red : .blue)
}
}
Button {
action()
} label: {
RingSegment()
// 使用我们在自定义按钮样式中设置的前景色
.fill(.foreground)
}
.buttonStyle(LightGrayRingSegmentButtonStyle())
英文:
The solution I went for is to apply the foregroundColor
modifier inside the makeBody
function and use that color when filling my custom shape.
This is my code:
// Declare Button Style
struct LightGrayRingSegmentButtonStyle: ButtonStyle {
func makeBody(configuration: Self.Configuration) -> some View {
configuration.label
.foregroundColor(configuration.isPressed ? .red : .blue)
}
}
Button {
action()
} label: {
RingSegment()
// respect foregroundColor which we set inside the custom button style
.fill(.foreground)
}
.buttonStyle(LightGrayRingSegmentButtonStyle())
</details>
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论