当.ondrag()结束而没有任何动作的能力(即
我正在使用.ondrag修饰符启用拖放操作:
struct RootView: View {
@State var dragging: Bool = false
var body: some View {
VStack {
Color.red.cornerRadius(.some)
.frame(width: 100, height: 100)
.onDrag {
dragging = true
return NSItemProvider(object: NSString())
}
}
}
}
一旦调用拖动,我将draging
标志设置为真。
进行下降没有问题。但是,如果我调用了一个拖动但没有任何动作而结束它,则我没有通知,即拖动
仍将设置为true。
我尝试将第二个手势设置添加到没有任何感知运动的情况下结束的拖曳手势的高价或同时的手势:
.gesture(DragGesture(minimumDistance: 0)
.onEnded({ value in
if value.translation.height == 0 && value.translation.width == 0 {
self.dragging = false
}
})
)
不管我是否将其放置在Ondrag修饰符之前/之后,它都会阻止Ondrag触发。
有什么办法能够分辨出何时结束而没有任何动作,即立即释放阻力?
I’m using the .onDrag modifier to enable a drag/drop operation:
struct RootView: View {
@State var dragging: Bool = false
var body: some View {
VStack {
Color.red.cornerRadius(.some)
.frame(width: 100, height: 100)
.onDrag {
dragging = true
return NSItemProvider(object: NSString())
}
}
}
}
As soon as a drag is invoked, I set the dragging
flag to be true.
There’s no issue with performing a drop. However, if I invoked a drag but ended it without any movement, I’m not informed, i.e. dragging
remains set to true.
I’ve tried adding a second gesture set to either highPriority or simultaneous of a drag gesture that ends without any perceived movement:
.gesture(DragGesture(minimumDistance: 0)
.onEnded({ value in
if value.translation.height == 0 && value.translation.width == 0 {
self.dragging = false
}
})
)
Regardless of whether I place it before/after the onDrag modifier, it stops the onDrag from triggering.
Is there any way to be able to tell when an onDrag ends without any movement, i.e. drag released immediately?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
我无法与Apple一起在Swiftui中实现上述问题,这是我得到的回应:
这无用,至少是基于我对提议的理解的理解。当我添加以下内容时:
和:
打印语句从未发生在阻力上。
但是,如果我做到了:
长媒体手势截距并停止阻力。更改最小持续时间似乎没有改变。也没有测序手势修饰符的顺序。或者如果设置了其他“虚拟”阻力为高优先级手势。
因此,我最终得到了不完美的创意解决方法。
首先,在根视图中,我添加了取消代表:
...
其目的是确保可拖动视图立即被潜在的落下目标包围。我有一个视图模型,可以保留何时输入下降目标的记录。
在卡的拖放处理程序中,我检查了3秒后检查卡是否已移动。我可以通过参考取消倾向的值的值来说明。如果它不到3秒钟,那么可以合理地假设它已经移动了,所以我无需做任何事情。但是,如果它是3个或更多,那么可以安全地假设该阻力是在过去3秒内在某个时刻发布的,因此我应该将其用作提示重置应用程序状态的提示。
这不是完美的原因是因为UI重置不会立即发生。在测试中,当系统决定由于未检测到的运动而决定将视图上的阻力驱动时,似乎存在3秒钟(该视图不再出现在系统最初被激活的阻力状态中)。因此,从这个角度来看,3秒钟很好。但是,如果我要在没有任何动作的情况下自己释放卡片,那么在UI意识到由于被驱动而需要重置的2秒钟(3-1),它将是2秒(3-1)。
希望这会有所帮助。如果有人有更好的解决方案,我全都是耳朵!
I filed the inability to achieve the above in SwiftUI with Apple, and this is the response I got:
This wasn't helpful, at least based on my understanding on what was proposed. When I added the following:
And:
The print statements never occurred on a drag.
If however I did:
The long press gesture intercepts and stops the drag. Changing the minimum duration didn’t seem to make a difference. Nor the order in which the gesture modifiers are sequenced. Or if the additional “dummy” drag is set to be a high priority gesture.
So I ended up with a not-perfect creative workaround.
Firstly, to the root view I added a cancellation delegate:
...
Its purpose is to ensure that the draggable view is immediately surrounded by a potential drop target. I have a view model for it that keeps a record for when a drop target has been entered.
In the card’s drag handler, I check after 3 seconds whether the card has moved. I can tell by referring to the cancellation’s dropLastEntered value. If it’s been less than 3 seconds, then it’s reasonable to assume it has moved and so there’s nothing I need to do. However if it’s been 3 or more, then it’s equally safe to assume that the drag was released at some point within the last 3 seconds, and so I should use this as a cue to reset the app state.
The reason this isn’t perfect is because the UI reset doesn’t happen immediately. In tests, 3 seconds appears to be around when the system decides to de-activate the drag on the view due to no movement detected (the view no longer appears in the drag state the system originally activated). So, from this perspective 3 seconds is good. However, if I was to release the card myself after 1 second without any movement, then it will be another 2 seconds (3-1) before the UI realises it needs to reset due to the drag being de-activated.
Hope this helps. If someone has a better solution, I’m all ears!