SwiftUI:自定义按钮无法识别具有清晰背景和 buttonStyle 的触摸
Posted
技术标签:
【中文标题】SwiftUI:自定义按钮无法识别具有清晰背景和 buttonStyle 的触摸【英文标题】:SwiftUI: Custom button does not recognize touch with clear background and buttonStyle 【发布时间】:2020-04-21 19:59:47 【问题描述】:我偶然发现了 SwiftUI 中 Button
s 与自定义 ButtonStyle
相结合的奇怪行为。
我的目标是创建一个带有某种“推回动画”的自定义ButtonStyle
。我为此使用了以下设置:
struct CustomButton<Content: View>: View
private let content: () -> Content
init(content: @escaping () -> Content)
self.content = content
var body: some View
VStack
Button(action: ... )
content()
.buttonStyle(PushBackButtonStyle(pushBackScale: 0.9))
private struct PushBackButtonStyle: ButtonStyle
let pushBackScale: CGFloat
func makeBody(configuration: Self.Configuration) -> some View
configuration
.label
.scaleEffect(configuration.isPressed ? pushBackScale : 1.0)
// Preview
struct Playground_Previews: PreviewProvider
static var previews: some View
CustomButton
VStack(spacing: 10)
HStack
Text("Button Text").background(Color.orange)
Divider()
HStack
Text("Detail Text").background(Color.orange)
.background(Color.red)
当我现在尝试在Text
视图之外触摸此按钮时,什么都不会发生。没有动画可见,也不会调用动作块。
到目前为止我发现了什么:
当您删除.buttonStyle(...)
时,它会按预期工作(当然没有自定义动画)
或者当您在CustomButton
中的VStack
上设置.background(Color.red))
时,它也可以与.buttonStyle(...)
结合使用。
现在的问题是,是否有人对如何正确解决此问题或如何解决问题有更好的了解?
【问题讨论】:
【参考方案1】:只需在您的自定义按钮样式中添加命中测试内容形状,如下所示
使用 Xcode 11.4 / ios 13.4 测试
private struct PushBackButtonStyle: ButtonStyle
let pushBackScale: CGFloat
func makeBody(configuration: Self.Configuration) -> some View
configuration
.label
.contentShape(Rectangle()) // << fix !!
.scaleEffect(configuration.isPressed ? pushBackScale : 1.0)
【讨论】:
我浪费了我生命中的一个小时试图解决这个问题。谢谢!【参考方案2】:只需使用 .frame 即可。 为了使其易于测试,我将其重写如下:
struct CustomButton: View
var body: some View
Button(action: )
VStack(spacing: 10)
HStack
Text("Button Text").background(Color.orange)
.frame(minWidth: 0, maxWidth: .infinity)
.background(Color.orange)
Divider()
HStack
Text("Detail Text").background(Color.orange)
.frame(minWidth: 0, maxWidth: .infinity)
.background(Color.orange)
.buttonStyle(PushBackButtonStyle(pushBackScale: 0.9))
private struct PushBackButtonStyle: ButtonStyle
let pushBackScale: CGFloat
func makeBody(configuration: Self.Configuration) -> some View
configuration
.label
.scaleEffect(configuration.isPressed ? pushBackScale : 1.0)
我希望我能帮上忙。 :-)
@用视频编辑。
【讨论】:
我明白你在想什么。这可能在这个用例中有效,但在更复杂的用例中也存在Spacer()
,它不再有效,因为Text
不能具有完整的宽度/高度。
使用 Spacer() 查看我的最小编辑答案。它确实按预期工作。 SwiftUI 中的文本与“.infinity”所允许的位置一样多。当然,你也可以定义一个值。
但我最初的用例是在Button
的Stack
和Spacer
inside 中,正如您在我的Playground_Previews
中看到的那样。在那里我认为它不会起作用。
在我的回答中添加了这个场景并制作了一个视频来向你展示它的工作原理。当然,Asperis 的答案也很好。以上是关于SwiftUI:自定义按钮无法识别具有清晰背景和 buttonStyle 的触摸的主要内容,如果未能解决你的问题,请参考以下文章