我想将一个视图拖动到ZStack. 在此示例代码中,Toolbar有一个蓝色的可拖动区域。通过设置 .它应该Toolbar在屏幕上移动offset。相反,它会进入无限循环。如何固定才能正确拖动?
它永远打印以下内容:
改变 (36.5, 27.0)
改变 (0.0, 0.0)
extension CGPoint {
func toSize() -> CGSize { .init(width:x, height:y) }
}
struct ContentView: View {
@State var offset: CGSize = .zero
var body: some View {
ZStack(alignment: .topLeading) {
Toolbar(dragOffset: $offset)
.offset(offset)
Text(verbatim: "Offset: \(offset)")
.frame(maxWidth: .infinity, maxHeight: .infinity)
}
}
}
struct Toolbar: View {
@Binding var dragOffset: CGSize
var body: some View {
HStack {
Color.blue.frame(width: 40, height: 40)
.gesture(drag)
Color.green.frame(width: 40, height: 40)
Color.red.frame(width: 40, height: 40)
}
}
var drag: some Gesture {
DragGesture()
.onChanged { value in
print("changed \(value.location)")
dragOffset = value.location.toSize()
}
.onEnded { value in
print("ended")
}
}
}
Run Code Online (Sandbox Code Playgroud)
我需要指定 a CoordinateSpace,因为默认值是.local. 使用.global作品。命名空间也应该有效。
@State将初始偏移记录在变量中,然后使用该起始值加上拖动的 来设置新值也很有帮助translation。
@State private var dragStartOffset: CGSize? = nil
...
DragGesture(coordinateSpace: .global)
.onChanged { value in
if dragStartOffset == nil {
dragStartOffset = dragOffset
}
dragOffset = dragStartOffset! + value.translation
}
.onEnded { _ in
dragStartOffset = nil
}
Run Code Online (Sandbox Code Playgroud)
您应该在offset之前应用gesture。
这可以确保您不会在屏幕上拖动时创建无限循环,偏移会发生变化,然后再次更改视图的位置。这意味着您的手势偏移现已更改,从而创建了无限循环。
变化:
struct ContentView: View {
@State var offset: CGSize = .zero
var body: some View {
ZStack(alignment: .topLeading) {
Toolbar(dragOffset: $offset)
// .offset(offset) // <- REMOVE THIS
Text(verbatim: "Offset: \(offset)")
.frame(maxWidth: .infinity, maxHeight: .infinity)
}
}
}
Run Code Online (Sandbox Code Playgroud)
struct Toolbar: View {
@Binding var dragOffset: CGSize
var body: some View {
HStack {
Color.blue.frame(width: 40, height: 40)
.offset(dragOffset) // <- ADD THIS
.gesture(drag)
Color.green.frame(width: 40, height: 40)
.offset(dragOffset) // <- ADD THIS
Color.red.frame(width: 40, height: 40)
.offset(dragOffset) // <- ADD THIS
}
}
/* ... */
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
981 次 |
| 最近记录: |