SwiftUI: пользовательская кнопка не распознает прикосновения с четким фоном и buttonStyle - PullRequest
0 голосов
/ 21 апреля 2020

Я наткнулся на странное поведение для Button s в SwiftUI в сочетании с пользовательским ButtonStyle.

Моя цель состояла в том, чтобы создать пользовательский ButtonStyle с каким-то 'pu sh обратная анимация. Для этого я использовал следующую настройку:

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, ничего не произойдет. Анимация не будет видна, и блок действий не будет вызван.

showcase

Что я обнаружил до сих пор:

  • когда вы удаляете .buttonStyle(...), он работает должным образом (конечно, никакой пользовательской анимации)
  • или когда вы устанавливаете .background(Color.red)) на VStack в CustomButton, он также работает должным образом в сочетании с .buttonStyle(...)

Теперь вопрос в том, есть ли у кого-нибудь лучшее представление о том, как правильно обойти эту проблему или как ее исправить?

Ответы [ 2 ]

1 голос
/ 22 апреля 2020

Просто добавьте форму содержимого для проверки попадания в свой собственный стиль кнопок, как показано ниже

Протестировано с Xcode 11.4 / iOS 13.4

demo

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)
    }
}
0 голосов
/ 21 апреля 2020

Просто используйте .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)
    }
}

Я надеюсь, что смогу помочь. : -)

@ Редактировать с видео.

enter image description here

...