SwiftUI — Перетаскивание кругов

#ios #swift #user-interface #swiftui #drag-and-drop

#iOS #swift #пользовательский интерфейс #swiftui #перетаскивание

Вопрос:

Я пытаюсь создать круги, которые можно перетаскивать.

Я могу заставить его работать только с первым кругом, однако все, что после первого, не работает.

Ожидаемое поведение: круг следует за моим курсором при перетаскивании и попадает в конечную позицию, когда перетаскивание заканчивается

Фактическое поведение: круг следует за горизонтальным положением моего курсора, но не за вертикальным положением (вертикальное положение всегда значительно ниже моего курсора)

ContentView.swift

 import SwiftUI

struct ContentView: View {
    var body: some View {
        VStack(alignment: .center) {
            ForEach(0..<5) { _ in
                DraggableCircles()
            }
        }
    }
}

struct ContentView_Previews: PreviewProvider {
    static var previews: some View {
        ContentView()
    }
}

struct DraggableCircles: View {
    @State var dragAmount: CGPoint = CGPoint.zero

        var body: some View {
            Circle().fill(Color.red)
            .frame(width: 50, height: 50)
                .gesture(
                    DragGesture(coordinateSpace: .global).onChanged {action in
                        let location = action.location
                        let newWidth = location.x
                        let newHeight = location.y
                        let size = CGPoint(x: newWidth, y: newHeight)
                        self.dragAmount = size
                    }.onEnded{action in
                        let location = action.location
                        let newWidth = location.x
                        let newHeight = location.y
                        let size = CGPoint(x: newWidth, y: newHeight)
                        self.dragAmount = size
                    }
                )
                .position(x: dragAmount.x, y: dragAmount.y)
        }
        
    }


 

Ответ №1:

Вы должны добавить значение перетаскивания в последнее местоположение. Правильный расчет здесь.

 struct DraggableCircles: View {
    
    @State private var location: CGPoint = CGPoint(x: 50, y: 50)
    @GestureState private var startLocation: CGPoint? = nil
    
    var body: some View {
        
        // Here is create DragGesture and handel jump when you again start the dragging/
        let dragGesture = DragGesture()
            .onChanged { value in
                var newLocation = startLocation ?? location
                newLocation.x  = value.translation.width
                newLocation.y  = value.translation.height
                self.location = newLocation
            }.updating($startLocation) { (value, startLocation, transaction) in
                startLocation = startLocation ?? location
            }
        
        return Circle().fill(Color.red)
            .frame(width: 50, height: 50)
            .position(location)
            .gesture(dragGesture)
    }
}
 

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