SwiftUi使用。在使用最终位置的视图上同时使用。offset和position修改器时会发生什么?
在这里,当我尝试给视图一个初始位置时,我有这个问题,然后用户可以使用拖放手势将视图的位置更改为任何地方。尽管我已经仅通过.position(x:y:)
在视图上解决了问题,但在开始时,我正在考虑使用.position(x:y:)
给出初始位置和.offset(offset:)
以同时以手势移动。现在,我真的只想更详细地知道,当我同时使用两个时(下面的代码)时,会发生什么,这样我就可以解释下面的视图中发生的情况。
我在下面的视图中无法解释的是:当我简单地将手势拖动在VSTACK框上时,它可以按预期工作,而VSTACK则以指手势移动,但是,一旦手势结束并尝试在VSTACK上启动一个新的拖放手势,VSTACK框突然返回原始位置(就像加载代码时跳到原始位置),然后开始以手势移动。请注意,手势是作为常规手势移动的,但是Vstack已经跳到了另一个位置,因此它开始从其他位置移动。这导致手指尖在VSTACK框的顶部不长,但是持续了一段距离,尽管VSTACK的移动与阻力手势相同。
我的问题是:为什么.position(x:y:)
修饰符似乎仅在检测到的每个新的阻力手势的最初生效,但是在对其进行阻力手势动作时,它似乎。 Offset(OFFSET:)
主导主要运动,Vstack停在将其拖动到达的位置。但是,一旦开出了新的阻力手势,Vstack突然跳到了原始位置。我只是无法围绕这种行为通过时间表而围绕着我的头。有人可以提供一些见解吗?
请注意,我已经解决了问题以实现我需要的问题,现在只是要了解.position(x:y:)
and .offset(offset(offset :)
同时使用,因此请避免使用一些建议。不同时使用它们,谢谢。 bellow代码假设在复制和粘贴后可以运行,如果我删除了几行以使重现问题更清洁时,我会因为犯错而赦免我。
import SwiftUI
struct ContentView: View {
var body: some View {
ButtonsViewOffset()
}
}
struct ButtonsViewOffset: View {
let location: CGPoint = CGPoint(x: 50, y: 50)
@State private var offset = CGSize.zero
@State private var color = Color.purple
var dragGesture: some Gesture {
DragGesture()
.onChanged{ value in
self.offset = value.translation
print("offset onChange: \(offset)")
}
.onEnded{ _ in
if self.color == Color.purple{
self.color = Color.blue
}
else{
self.color = Color.purple
}
}
}
var body: some View {
VStack {
Text("Watch 3-1")
Text("x: \(self.location.x), y: \(self.location.y)")
}
.background(Color.gray)
.foregroundColor(self.color)
.offset(self.offset)
.position(x: self.location.x, y: self.location.y)
.gesture(dragGesture)
}
}
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
Group {
ContentView()
}
}
}
Here I have this question when I try to give a View an initial position, then user can use drag gesture to change the location of the View to anywhere. Although I already solved the issue by only using .position(x:y:)
on a View, at the beginning I was thinking using .position(x:y:)
to give initial position and .offset(offset:)
to make the View move with gesture, simultaneously. Now, I really just want to know in more detail, what exactly happens when I use both of them the same time (the code below), so I can explain what happens in the View below.
What I cannot explain in the View below is that: when I simply drag gesture on the VStack box, it works as expected and the VStack moves with finger gesture, however, once the gesture ends and try to start a new drag gesture on the VStack, the VStack box goes back to the original position suddenly (like jumping to the original position when the code is loaded), then start moving with the gesture. Note that the gesture is moving as regular gesture, but the VStack already jumped to a different position so it starts moving from a different position. And this causes that the finger tip is no long on top of the VStack box, but off for some distance, although the VStack moves with the same trajectory as drag gesture does.
My question is: why the .position(x:y:)
modifier seems only take effect at the very beginning of each new drag gesture detected, but during the drag gesture action on it seems .offset(offset:)
dominates the main movement and the VStack stops at where it was dragged to. But once new drag gesture is on, the VStack jumps suddenly to the original position. I just could not wrap my head around how this behavior happens through timeline. Can somebody provide some insights?
Note that I already solved the issue to achieve what I need, right now it's just to understand what is exactly going on when .position(x:y:)
and .offset(offset:)
are used the same time, so please avoid some advice like. not use them simultaneously, thank you. The code bellow suppose to be runnable after copy and paste, if not pardon me for making mistake as I delete few lines to make it cleaner to reproduce the issue.
import SwiftUI
struct ContentView: View {
var body: some View {
ButtonsViewOffset()
}
}
struct ButtonsViewOffset: View {
let location: CGPoint = CGPoint(x: 50, y: 50)
@State private var offset = CGSize.zero
@State private var color = Color.purple
var dragGesture: some Gesture {
DragGesture()
.onChanged{ value in
self.offset = value.translation
print("offset onChange: \(offset)")
}
.onEnded{ _ in
if self.color == Color.purple{
self.color = Color.blue
}
else{
self.color = Color.purple
}
}
}
var body: some View {
VStack {
Text("Watch 3-1")
Text("x: \(self.location.x), y: \(self.location.y)")
}
.background(Color.gray)
.foregroundColor(self.color)
.offset(self.offset)
.position(x: self.location.x, y: self.location.y)
.gesture(dragGesture)
}
}
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
Group {
ContentView()
}
}
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
您的问题与位置和偏移的使用无关。他们实际上都同时工作。位置设置了视图的绝对位置,随着偏移量相对于绝对位置而移动。因此,您会注意到您的视图从屏幕上的位置(50,50)开始,然后您可以将其全部拖动。一旦放开,它就会在任何地方停止。到目前为止,一切都很好。然后,您想再次移动它,然后弹出回到原始位置。之所以这样做的原因是您将位置设置为“让恒定”的方式。它必须是状态。
该问题源于您在没有意识到位置的值的情况下添加的事实。完成阻力时,偏移保留了最后一个值。但是,当您启动下一个拖动时,这些值再次从(0,0)开始,因此偏移重置为(0,0),并且视图移回原始位置。关键是您需要仅使用该位置或更新
.goned
中的偏移量。不要同时使用两者。在这里,您有一个设定的位置,并且没有保存偏移。如何处理它取决于您正在移动视图的目的。首先,只需使用
.position()
:第二,只需使用
.offset()
:Your issue has nothing to do with the use of position and offset. They actually both work simultaneously. Position sets the absolute position of the view, where as offset moves it relative to the absolute position. Therefore, you will notice that your view starts at position (50, 50) on the screen, and then you can drag it all around. Once you let go, it stops wherever it was. So far, so good. You then want to move it around again, and it pops back to the original position. The reason it does that is the way you set up location as a let constant. It needs to be state.
The problem stems from the fact that you are adding, without realizing it, the values of offset to position. When you finish your drag, offset retains the last values. However, when you start your next drag, those values start at (0,0) again, therefore the offset is reset to (0,0) and the view moves back to the original position. The key is that you need to use just the position or update the the offset in
.onEnded
. Don't use both. Here you have a set position, and are not saving the offset. How you handle it depends upon the purpose for which you are moving the view.First, just use
.position()
:Second, just use
.offset()
: