我正在使用偏移量和手势修饰符在屏幕上移动一个圆圈。当我使用此代码时,一切都会按预期进行:
import SwiftUI
struct MovingCircle: View {
@State private var dragged = CGSize.zero
var body: some View {
Circle()
.offset(x: self.dragged.width)
.frame(width: 20, height: 20)
.gesture(DragGesture()
.onChanged{ value in
self.dragged = value.translation
}
.onEnded{ value in
self.dragged = CGSize.zero
}
)
}
}
但是,我不想将圆重置为onEnded的原始位置。我希望它保持原位,然后在拖动时再次移动。当我使用以下代码时,在重新拖动时,我失去了再次移动圆环的功能,并且圆环仍保持在原处:
import SwiftUI
struct MovingCircle: View {
@State private var dragged = CGSize.zero
var body: some View {
Circle()
.offset(x: self.dragged.width)
.frame(width: 20, height: 20)
.gesture(DragGesture()
.onChanged{ value in
self.dragged = value.translation
}
.onEnded{ value in
self.dragged = value.translation
}
)
}
}
这是什么原因,我是否遇到了一些错误或编码不正确?
答案 0 :(得分:1)
首先,要了解该问题,请在.border(Color.red)
修饰符中添加一个.frame()
:
.frame(width: 20, height: 20).border(Color.red)
您将看到,当移动点时,其框架仍保留在原位。这就是为什么以后它不会响应手势的原因。 “可敲击”区域不再与点匹配。而且由于内容区域现在为空,因此不再是“可插拔的”。
要使框架随点移动,请颠倒顺序。 .offset()
应该稍后出现:
.frame(width: 20, height: 20).border(Color.red)
.offset(x: self.dragged.width)
最后,您会看到在每个.onEnded()
之后,整个事情都会重置。解决此问题的一种方法是,累积您在以前的手势中拖了多少:
struct MovingCircle: View {
@State private var dragged = CGSize.zero
@State private var accumulated = CGSize.zero
var body: some View {
Circle()
.frame(width: 20, height: 20).border(Color.red)
.offset(x: self.dragged.width)
.gesture(DragGesture()
.onChanged{ value in
self.dragged = CGSize(width: value.translation.width + self.accumulated.width, height: value.translation.height + self.accumulated.height)
}
.onEnded{ value in
self.dragged = CGSize(width: value.translation.width + self.accumulated.width, height: value.translation.height + self.accumulated.height)
self.accumulated = self.dragged
}
)
}
}
答案 1 :(得分:0)
Swift 5.x iOS 13
一种不太优雅的解决方案,如果您不希望看到对象被拖动;您只希望能够拖动它;如果您正在进行很多工作,并且希望节省CPU,则可能更有意义。
显然,您需要为其找到一个更好的起始位置,然后再使其变为绝对零。
import SwiftUI
var intern:CGPoint = CGPoint(x:0,y:0)
enum DragState {
case inactive
case dragging(translation: CGSize)
}
struct ContentView: View {
@State var position:CGPoint = CGPoint(x:0,y:0)
@GestureState private var dragState = DragState.inactive
var body: some View {
ZStack {
Circle()
.frame(width: 24, height: 24, alignment: .center)
}.offset(x: self.dragOffset.width, y: self.dragOffset.height)
.gesture(DragGesture(coordinateSpace: .global)
.updating($dragState, body: { (drag, state, translation)
intern = drag.location
})
.onEnded { ( value ) in
self.position = intern
}
).position(position)
}
}