Jak mogę zaktualizować lokalizację X dla przesunięcia w dokładnym punkcie dotknięcia widoku w SwiftUI?

Nov 21 2020

Próbuję zaktualizować moje przesunięcie Rec za pomocą gestu przeciągnięcia tego Rec, już zakodowałem w ten sposób, że Rec zaczyna się poruszać w zależności od przeciągania i podąża za oporem podczas kodowania, problem, który otrzymuję z tym polega na tym, że sam się wyśrodkowuje zawsze i nie mogę wyciągnąć Rec z ekranu, moim celem jest kodowanie w taki sposób, aby offset zaczął działać z między lokalizacjami tagu i stał się źródłem offsetu, teraz źródło jest w środku, co lubię być dynamiczne i elastyczne, jak stuknij w Rec. Jak mam to zakodować?

    struct ContentView: View {
    

    @State var locationX: CGFloat = .zero
    let widthOfRec: CGFloat = 200
    
    var body: some View {

        Rectangle()
            .fill(Color.red)
            .frame(width: widthOfRec)
            .border(Color.black)
            .offset(x: locationX - widthOfRec/2)
            .gesture( DragGesture().onChanged { value in locationX = value.location.x })
        
        
        
        
    }
}

Odpowiedzi

Asperi Nov 21 2020 at 18:12

Jeśli dobrze zrozumiałem twój cel, musisz użyć GestureState. Stan gestu ma wartość tymczasową, która po zakończeniu gestu jest resetowana do stanu początkowego.

Oto demo możliwego rozwiązania. Przygotowano z Xcode 12.1 / iOS 14.1

struct ContentView: View {
    
    @State var locationX: CGFloat = .zero
    @GestureState private var translationX = CGFloat.zero

    let widthOfRec: CGFloat = 200
    
    var body: some View {

        Rectangle()
            .fill(Color.red)
            .frame(width: widthOfRec)
            .border(Color.black)
            .offset(x: locationX + translationX)
            .gesture(
                DragGesture().updating($translationX) { value, state, _ in
                    state = value.translation.width
                }.onEnded { value in
                    locationX += value.translation.width
                }
            )
    }
}