#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)
}
}