SwiftUI: отмена TapGesture в родительском представлении - PullRequest
2 голосов
/ 28 января 2020

У меня есть иерархия представлений в SwiftUI, например

ParentView { 
//other views

ChildView().highPriorityGesture(TapGesture().onEnded {
                        print("Tap!")
                    })
// other views 
}self.gesture(tap)

И я хочу, чтобы родительский просмотр обрабатывал все касания на экране, несмотря на случаи, когда пользователь нажимает на ChildView. Теперь оба замыкания выполняются. Как остановить события жеста касания, распространяющиеся вверх по иерархии представления?

1 Ответ

0 голосов
/ 28 января 2020

Ну, вероятно, есть некоторые специфические c, в которых точно ChildView и ParentView, потому что, как проверено ниже (Xcode 11.2 / iOS 13.2), жест дочернего представления просто переопределяет жест родительского представления.

Здесь демонстрация .. нажатие в желтой области, затем нажатие в зеленой области - никаких обратных вызовов смешивания

enter image description here

Полный код модуля

import SwiftUI

struct TestGesturesPriority: View {
    var body: some View {
        VStack {
            Text("Hello, World!")
                .padding()
                .background(Color.yellow)
                .gesture(TapGesture().onEnded {
                    print(" -- child")
                })
        }
        .frame(width: 400, height: 400)
        .background(Color.green)
        .gesture(TapGesture().onEnded {
            print(">> parent")
        })
    }
}

Обновление: вариант для List-Row

Да ... Список (Родитель) - Ряд (Ребенок) дело показалось очень сложным ... пожалуйста найти подход ниже, это выглядит странно, но проверено и работает

struct TestGesturesPriority: View {

    let parentGesture = TapGesture().onEnded { // just for convenience
        print(">> parent")
    }

    @GestureState private var captured = false
    var body: some View {
        List {
            Text("Hello, World!").padding()
                    .background(Color.yellow)
                    .allowsHitTesting(true)
                    .gesture(DragGesture(minimumDistance: 0) // mimic Tap
                        .updating($captured, body: { (value, state, transaction) in
                        state = true // mark captured (will be reset automatically)
                    })
                    .onEnded { value in
                        // like Tap, but can be ignored if delta 
                        // is large or out of view
                        print(" -- child")
                    }
                )
        }
        .gesture(parentGesture, including: captured ? .subviews : .gesture)
    }
}

Подводя итог - на самом деле я думаю, что это еще один дефект списка

...