SwiftUI按钮如何响应绘制范围之外的触摸

3

我用 ButtonStyle 创建了一个有样式的按钮。 我在我的视图中使用此按钮,如下所示:

Button("取消", action: onCancel).buttonStyle(FormButtonStyle(mode: .normal)

在某些地方,我会在按钮上方添加 padding:

.padding(.init(arrayLiteral: .trailing, .leading), 16)

但是,这些按钮响应超出其绘制范围的触摸事件。 我该如何防止这种情况发生? 在下面的示例中,点击 Cancel 按钮将触发 Save 按钮。 即使添加了padding,也会发生这种情况。 大多数这些按钮位于用于选择多个项目的 List 的底部。例如,在我的应用程序中,我有一个 SaveCancel 按钮。

private var actionBtns: some View {
        VStack(spacing: 8){
            Divider().foregroundColor(Color.veryLightPinkThree)
            Button("Save", action: onSave).buttonStyle(CustomButtonStyle(mode: .normal))
                .padding(.init(arrayLiteral: .trailing, .leading), 16)
            Button("Cancel", action: onCancel).buttonStyle(CustomButtonStyle(mode: .success))
                .padding(.init(arrayLiteral: .trailing, .leading), 16)
        }
        .backgroundColor(.offWhite)
    }

这个actionsBtns视图被添加到了我 SwiftUI 视图的主体中。

import PureSwiftUI
import SwiftUI


struct CustomButtonStyle: ButtonStyle {
    enum Weight {
        case normal
        case compact

        func fontSize() -> Double {
            switch self {
            default:
                return 16.0
            }
        }

        func hPadding() -> CGFloat {
            switch self {
            case .normal:
                return 16.0

            case .compact:
                return 16.0
            }
        }

        func height() -> CGFloat {
            switch self {
            case .normal:
                return 56.0

            case .compact:
                return 40.0
            }
        }

        func width() -> CGFloat {
            switch self {
            case .normal:
                return 150.0
            case .compact:
                return 75.0

            }
        }

    }

    enum Mode {
        case normal
        case success
        case destroy
        case greenOutline
        case dark

        func foregroundColor(isEnabled: Bool = true) -> Color {
            switch self {
            case .success, .dark, .destroy:
                return Color.white

            case .greenOutline:
                return  isEnabled  ? .mediumGreen : .veryLightPinkFour

            default:
                return isEnabled ? Color.greyishBrown : Color.white
            }
        }

        func backgroundColor(isEnabled: Bool = true) -> Color {
            switch self {
            case .destroy:
                return isEnabled ? Color.pinkishOrange : Color.veryLightPinkThree

            case .success:
                return isEnabled ? Color.mediumGreen : Color.veryLightPinkThree

            case .greenOutline:
                return .white

            case .dark:
                return Color.greyishBrown

            default:
                return isEnabled ? Color.offWhite : Color.veryLightPinkThree
            }
        }

        func strokeColor(isEnabled: Bool = true) -> Color {
            switch self {
            case .normal:
                return isEnabled ? Color.veryLightPinkThree: Color.veryLightPinkTwo

            case .greenOutline:
                return .mediumGreen

            default:
                return Color.clear
            }
        }
    }

    var mode: Mode = .normal
    var weight: Weight = .normal

    func makeBody(configuration: ButtonStyle.Configuration) -> some View {
        CustomButton(configuration: configuration, mode: mode, weight: weight)
    }

    struct CustomButton: View {
        @SwiftUI.Environment(\.isEnabled) var isEnabled: Bool

        var configuration: ButtonStyle.Configuration
        var mode: FormButtonStyle.Mode
        var weight: FormButtonStyle.Weight

        init(configuration: ButtonStyle.Configuration, mode: FormButtonStyle.Mode, weight: FormButtonStyle.Weight) {
            self.configuration = configuration
            self.mode = mode
            self.weight = weight
        }


        var body: some View {
            configuration.label
            .lineLimit(1)
            .greedyWidth()
            .height(weight.height())
            .padding(.horizontal, weight.hPadding())
            .fontSize(weight.fontSize(), weight: .bold)
            .foregroundColor(mode.foregroundColor(isEnabled: isEnabled))
            .backgroundColor(mode.backgroundColor(isEnabled: isEnabled))
            .clipRoundedRectangleWithStroke(weight.height() / 2.0, mode.strokeColor(isEnabled: isEnabled), lineWidth: 1)
            .compositingGroup()
        }
}

由于缺少许多自定义依赖项,所提供的代码无法进行测试。 - undefined
尝试将".contentShape(Rectangle())"添加到你的按钮中。 - undefined
@workingdog 我已经尝试过了,但没有成功。 - undefined
没有简单的示例代码,我们无法粘贴和运行,我只能说一句话:.contentShape() 是你需要的工具。 - undefined
如何创建一个最小化、可复现的示例 - undefined
你检查了你的视图层次结构吗? - undefined
1个回答

1

如果您正在使用 List 和每行内部的按钮,请设置 .buttonStyle(.borderless)


这在我的情况下确实有效。 - undefined

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接