Почему жест начинает работать вне фрейма в SwiftUI?

#swiftui

#swiftui

Вопрос:

У меня есть рекомендация, что я могу переместить его в действие жеста, но проблема в том, что жест начинает захватывать жест за пределами его фрейма, который, как я ожидаю, работает только внутри фрейма. вот код и gif-файл о проблеме:

gif — файл:

введите описание изображения здесь

код:

     struct ContentView: View {
    
    @State private var recLocation: CGFloat = CGFloat()
    @GestureState private var recTranslation: CGFloat = CGFloat()
    
    var body: some View {
        
        GeometryReader { geometry in
            
            Rectangle().fill(Color.red).frame(width: 50, height: 50, alignment: .center)
                .position(x: recLocation   recTranslation   25, y: geometry.size.height/2)
                .gesture( DragGesture()
                            .updating($recTranslation) { value, state, translation in
                                state = value.translation.width
                            }
                            .onEnded { value in
                                recLocation = recLocation   value.translation.width
                            } )
            
            
        }
        
    }
}
 

Комментарии:

1. Я думаю, что .position() охватывает все доступное пространство контейнера. Поскольку .gesture() присоединяется (идет после) .position() , это то, что в конечном итоге получает событие. Возможно, вы могли бы попробовать переместить .gesture() перед .position() и посмотреть, что произойдет?

Ответ №1:

Из того, что я знаю, каждый раз, когда я использую GeometryReader размеры моего контейнера, я перепутал, я пытался найти решение с первой минуты, когда вы опубликовали этот вопрос, потому что это очень интересно, и вот как преодолеть эту проблему:

 GeometryReader { geometry in
    
    Rectangle()
        .fill(Color.red)
        .frame(width: 50, height: 50)
        .position(x: recLocation   recTranslation   25, y: geometry.size.height/2)
        .overlay(
            Rectangle()
                .fill(Color.blue)
                .frame(width: 23.5, height: 23.5)
                .position(x: recLocation   recTranslation   25, y: geometry.size.height/2)
                .opacity(0.001)
                .gesture( DragGesture()
                            .updating($recTranslation) { value, state, translation in
                                state = value.translation.width
                            }
                            .onEnded { value in
                                recLocation = recLocation   value.translation.width
                            } )
        )
    
}.frame(width: 50, height: 50)
}
 

Объяснение:

По сути, я увидел, что объект DragGesture обнаружен за пределами границы вашего прямоугольника, благодаря чему я создал Overlay объект с той же формой и меньшим размером и превратил DragGesture его в Overlay .

Примечание: Не забудьте присвоить Overlay фигуре Opacity значение 0.001, тогда она будет невидимой, но все равно интерактивной.

Вуаля! все кажется идеальным.

Результат

Комментарии:

1. @ Cod3rMax: спасибо за ваш ответ, но я не могу принять, вы не решаете проблему, вы имеете дело с проблемой!

2. @willy большое вам спасибо 🙂 если вы найдете решение или что-то в этом роде, дайте мне знать, я был бы рад узнать, что, если никто не ответит так, как вы ожидаете, я начну щедрость, возможно, будут гораздо более простые решения.

3. @ Cod3rMax: определенно, к вашему сведению, я мог бы лучше справиться с проблемой чтения местоположения X крана или делать то же самое, что вы делали в фоновом режиме Rec, я здесь не для того, чтобы решать проблему, а для того, чтобы выяснить, почему это происходит. проблема в том, что мы работаем с доводчиками DragGesture() («Я имею в виду, что Apple заставляет нас работать с этим»), я не знаю, какова материнская функция DragGesture(), которая дает нам значение, состояние и перевод.

4. @willy я отправил запрос в службу поддержки инженерам Apple, чтобы точно объяснить, почему, второе, что вы должны опубликовать в своем вопросе, что вы пытались преодолеть проблему, и точно спросить (ПОЧЕМУ) в вашем вопросе, а не в вашем названии. Когда я получу от них ответ, я обновлю свой ответ

5. @ Cod3rMax: спасибо, я знаю, как я могу так легко преодолеть проблему и справиться с ней в одной короткой строке кода, но, как я уже сказал, я хочу решить проблему с помощью basic, не используя какой-либо другой код для решения проблемы, которая вообще не должна существовать. Я думаю, что у Apple есть еще один фрейм, больше, чем фрейм, к которому мы можем получить доступ, и этот фрейм создает проблему. Таким образом, вы создаете API, и у вас есть доступ только к исходному коду и к этому неизвестному фрейму.