Ios 快捷界面:自定义按钮无法识别背景清晰的触摸和按钮样式

Ios 快捷界面:自定义按钮无法识别背景清晰的触摸和按钮样式,ios,swift,swiftui,xcode11,Ios,Swift,Swiftui,Xcode11,我偶然发现SwiftUI中的按钮与自定义的按钮样式结合使用时出现了一种奇怪的行为 我的目标是创建一个自定义的按钮样式,带有某种“推后动画”。我为此使用了以下设置: struct自定义按钮:视图{ 私有出租内容:()->内容 init(内容:@escaping()->content){ self.content=内容 } var body:一些观点{ VStack{ 按钮(操作:{…}){ 内容() } .buttonStyle(PushBackButtonStyle(pushBackScale:

我偶然发现SwiftUI中的
按钮
与自定义的
按钮样式
结合使用时出现了一种奇怪的行为

我的目标是创建一个自定义的
按钮样式
,带有某种“推后动画”。我为此使用了以下设置:

struct自定义按钮:视图{
私有出租内容:()->内容
init(内容:@escaping()->content){
self.content=内容
}
var body:一些观点{
VStack{
按钮(操作:{…}){
内容()
}
.buttonStyle(PushBackButtonStyle(pushBackScale:0.9))
}
}
}
私有结构PushBackButtonStyle:ButtonStyle{
让pushBackScale:CGFloat
func makeBody(配置:Self.configuration)->一些视图{
配置
.标签
.scaleEffect(配置.isPressed?pushBackScale:1.0)
}
}
//预演
结构运动场\u预览:PreviewProvider{
静态var预览:一些视图{
自定义按钮{
VStack(间距:10){
HStack{
文本(“按钮文本”)。背景(颜色。橙色)
}
分隔器()
HStack{
文本(“详细文本”)。背景(颜色。橙色)
}
}
}
.背景(颜色.红色)
}
}
当我现在尝试触摸
文本
视图外部的此按钮时,不会发生任何事情。动画将不可见,并且不会调用动作块

到目前为止,我发现:

  • 当您删除
    .buttonStyle(…)
    时,它会按预期工作(当然没有自定义动画)
  • 或者,当您在
    自定义按钮中的
    VStack
    上设置
    .background(Color.red))
    时,它与
    按钮样式(…)

现在的问题是,是否有人对如何正确解决此问题或如何解决此问题有更好的想法?

只需使用.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)
    }
}
我希望我能帮忙。:-)

@用视频编辑


只需在自定义按钮样式中添加点击测试内容形状,如下所示

使用Xcode 11.4/iOS 13.4进行测试

private struct PushBackButtonStyle:ButtonStyle{
让pushBackScale:CGFloat
func makeBody(配置:Self.configuration)->一些视图{
配置
.标签

.contentShape(Rectangle())//我知道你在想什么。这在这个用例中可能会起作用,但在更复杂的用例中,也有一个
间隔符()
,它不再起作用,因为
文本不能具有全宽/全高。请参阅我用间隔符()编辑的最小答案.它确实按预期工作。SwiftUI中的文本占据了我们允许它与“.infinity”一起占据的位置。当然,你也可以定义一个值。但我最初的用例是在
按钮的
内部有一个
堆栈
间隔片
,正如你在我的
游乐场预览中所看到的那样。我认为它不会起作用。在我的回答中添加了这个场景,并制作了一个视频向你展示它的工作原理。然而,Asperis答案是正确的当然也很好。我浪费了一个小时的时间试图解决这个问题。谢谢!
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)
    }
}