Ответ
В SwiftUI модификаторы .gesture и .simultaneousGesture управляют тем, как представление обрабатывает жесты, особенно при их наложении.
.gesture(_:): Устанавливает эксклюзивный (исключающий) жест. Если на одном представлении или в иерархии есть несколько жестов, сработает только один (обычно первый подходящий или дочерний). Это поведение по умолчанию..simultaneousGesture(_:): Устанавливает жест, который может обрабатываться одновременно с другими жестами на том же представлении или в родительской иерархии.
Ключевое правило: Жесты обрабатываются от дочернего представления к родительскому. .gesture обычно "поглощает" событие, предотвращая его всплытие. .simultaneousGesture позволяет событию всплывать дальше.
Пример: Конфликт жестов на одном элементе
// Сработает ТОЛЬКО LongPressGesture, TapGesture будет проигнорирован.
Circle()
.gesture(LongPressGesture().onEnded { _ in print("Long Press") })
.gesture(TapGesture().onEnded { _ in print("Tap") }) // Не сработает
// Сработают ОБА жеста одновременно.
Circle()
.simultaneousGesture(LongPressGesture().onEnded { _ in print("Long Press") })
.simultaneousGesture(TapGesture().onEnded { _ in print("Tap") }) // Сработает
Пример: Иерархия представлений
// Родительский контейнер с TapGesture
Rectangle()
.gesture(TapGesture().onEnded { _ in print("Parent Tapped") }) {
// Дочерний круг с exclusive жестом
Circle()
.gesture(TapGesture().onEnded { _ in print("Child Tapped") }) // Сработает только этот
}
// Если заменить .gesture у Circle на .simultaneousGesture,
// сработают оба: "Child Tapped", а затем "Parent Tapped".