簡體   English   中英

SwiftUI:自定義按鈕無法識別具有清晰背景和按鈕樣式的觸摸

[英]SwiftUI: Custom button does not recognize touch with clear background and buttonStyle

我偶然發現了 SwiftUI 中Button與自定義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視圖之外觸摸此按鈕時,什么都不會發生。 沒有 animation 將可見,並且不會調用操作塊。

展示

到目前為止我發現了什么:

  • 當您刪除.buttonStyle(...)它確實按預期工作(當然沒有自定義 animation)
  • 或者當您在CustomButtonVStack上設置.background(Color.red))時,它也可以與.buttonStyle(...)

現在的問題是,是否有人對如何正確解決此問題或如何解決此問題有更好的了解?

只需在您的自定義按鈕樣式中添加命中測試內容形狀,如下所示

使用 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)
    }
}

只需使用 a.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)
    }
}

我希望我能幫上忙。 :-)

@用視頻編輯。

在此處輸入圖像描述

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM