Chr*_*itt 9 ipad ios swift swiftui ipados
我有一个应用程序,它有一个父视图(graphView,带有粗蓝色边框)和一个子视图(nodeView,绿色框)。每个都有自己的 SwiftUI DragGesture 处理程序。我希望能够用不同的手指移动绿色节点和蓝色边框图。
目标:当我主动拖动 \xe2\x80\x9c 蓝色边框图时,将 \xe2\x80\x9cgreen 节点 \xe2\x80\x9d 保持在我的手指下。\xe2\x80\x9d
\n问题:绿色节点 \xe2\x80\x9cghosts\xe2\x80\x9d,即似乎在位置周围反弹。
\n笔记:
\n.simultaneousGestureon nodeView 可以让我用一根手指在节点上同时拖动图形和节点。但我想用两个单独的手指拖动图形和节点:一个在节点上,另一个在图形上。.offset上的ZStack)被设置为模仿我的应用程序的实际设置。如果有更好的方法,我也愿意在 UIKit 中执行此操作。我怀疑目前的问题是来自图形与节点手势处理程序上的竞争“触发周期”。
\nstruct StackOverflowTestView: View {\n @State var graphOffset: CGFloat = .zero\n @State var graphPreviousOffset: CGFloat = .zero\n\n @State var nodePosition: CGFloat = 200.0\n @State var nodePreviousPosition: CGFloat = 200.0\n\n @State var nodeIsDragged = false\n\n @State var lastNodeTranslation: CGFloat = .zero\n\n var graphDrag: some Gesture {\n DragGesture()\n .onChanged { graphDragValue in\n graphOffset = graphPreviousOffset + graphDragValue.translation.height\n\n // If we\'re simultaneously dragging the node,\n // add inverse graph translation to node\'s position,\n // so that node stays under our finger:\n if nodeIsDragged {\n nodePosition = nodePreviousPosition + lastNodeTranslation - graphDragValue.translation.height\n }\n }\n .onEnded { _ in\n graphPreviousOffset = graphOffset\n }\n }\n\n var nodeDrag: some Gesture {\n // .local: node translation is relative to graph\'s translation,\n // e.g. graph +200, node -200 = node translation is -400\n // .global: node translation affected by graph\'s translation\n DragGesture(coordinateSpace: SwiftUI.CoordinateSpace.global)\n .onChanged { nodeDragValue in\n nodeIsDragged = true\n lastNodeTranslation = nodeDragValue.translation.height\n nodePosition = nodePreviousPosition + nodeDragValue.translation.height\n }\n .onEnded { _ in\n nodeIsDragged = false\n lastNodeTranslation = 0\n nodePreviousPosition = nodePosition\n }\n }\n\n var nodeView: some View {\n Rectangle()\n .fill(.green.opacity(0.9))\n .frame(width: 100, height: 100) // NODE SIZE\n .position(x: 500, y: nodePosition) // NODE POSITION\n .gesture(nodeDrag)\n }\n\n var graphView: some View {\n ZStack { nodeView }\n .border(.blue, width: 32)\n .offset(x: 0, y: graphOffset) // GRAPH OFFSET\n .background(Rectangle()\n .fill(.pink.opacity(0.1))\n .frame(width: 1200, height: 800)\n .gesture(graphDrag))\n }\n\n var body: some View {\n graphView.border(.yellow)\n }\n}\nRun Code Online (Sandbox Code Playgroud)\n
nodeDrag您需要将逆图翻译添加到-> DragGesture->内的节点位置.onChanged。您仅在内部添加graphDrag。
更改nodeDrag-> DragGesture-> .onChanged-> nodePosition = nodePreviousPosition + nodeDragValue.translation.height为
nodePosition = nodePreviousPosition + nodeDragValue.translation.height - (graphOffset - graphPreviousOffset)
仅供参考 -> 我重新排列以下方程以获得graphDragValue.translation.height
( graphOffset = graphPreviousOffset + graphDragValue.translation.height) 的值。如果你愿意,你可以使用一个单独的状态变量。
幽灵行为的解释
这就是您的代码所发生的情况。
当您移动 graphView 时,在内部graphDrag->.onChanged您将逆图平移添加到节点的位置。这是绝对正确的。所以这可以让你的nodeView保持在正确(相同)的位置。
但是如果你的手指在nodeView(绿色视图)上略有变化nodeDrag->.onChange方法 get 调用。在其中您正在设置一个nodePosition新值。在这里你忘记了你graphView已经搬家了。因此,如果 graphView 没有移动,nodeView 就会移动到它应该在的位置。
再次通过grapDrag->onChanged将nodeView移动到正确的位置。
所以这种情况不断发生,nodeView 不断在位置上弹跳。这会产生幽灵行为。
如果您将手指保持在 nodeView 上非常静止(这样就不会进行 onChange get 调用),您的代码将起作用。
按照我上面提到的更改代码即可解决问题。
| 归档时间: |
|
| 查看次数: |
642 次 |
| 最近记录: |