ios 为什么我的SwiftUI手势在Map上只能使用一次?

hc8w905p  于 2022-12-20  发布在  iOS
关注(0)|答案(1)|浏览(147)
    • 设置:**

我正在将应用程序从UIKit转换为SwiftUI。
应用程序现在使用SwiftUI Map而不是MKMapView
不幸的是,苹果并没有为Map提供MKMapView的所有功能,例如拖动Map注解和获取拖动终点的坐标。
无论如何,我正尝试在SwiftUI中实现一个类似的函数。这是我的注解视图的开发主体:

var body: some View {
    GeometryReader { geo in // 1
        let frameInGlobal = geo.frame(in: .global)
        Image("PinRed")
            .background(Color.green) // 2
            .offset(CGSize(width: dragAmount.width, height: dragAmount.height - liftOff)) // 3
            .defersSystemGestures(on: .all) // 4
            .onTapGesture {
                print("Global center: \(frameInGlobal.midX) x \(frameInGlobal.midY)")
            }
            .gesture(drag(frameInGlobal: frameInGlobal)) // 5
            .simultaneousGesture( // 6
                LongPressGesture(minimumDuration: 0.2)
                    .onEnded { _ in // 7
                        liftOff = 40.0
                }
            )
    }
    .frame(width: 30, height: 30)
    .background(Color.red) // 2
}

<1>GeometryReader用于在拖动过程中获取屏幕坐标。
<2>背景颜色在那里,以便它可以很容易地识别发生了什么。
<3>大头针图像偏移拖动量加上垂直位移,以便大头针在手指上方可见。
<4>系统手势(例如双击后放大和长按以拖动Map)被推迟,以便自定义手势通过。
<5>自定义拖动手势实质上会更改@GestureState var dragAmount = CGSize.zero,以便大头针图像跟随手指。
<6>需要simultaneousGesture,以便可以使用自定义点击手势和自定义长按手势。
<7>销被提离,表示可以开始拖动。

    • 问题:**

如果liftOff的值是0.0,我可以点击注解,它会打印出它的位置,我可以长按它并四处拖动它。拖动停止后,它仍然接受进一步的点击和长按。
然而,当liftOff值为40.0时,注解只能在不拖动的情况下点击,并且当第一次拖动注解时,不能再次拖动。这意味着自定义手势不再出现。相反,只有系统手势起作用。
以下是第一次拖动后的情况示例(绿色为图像背景,红色为GeometryReader背景)。

    • 问题:**

为什么自定义手势只在大头针没有被提起时才被接受?
怎么做才对?

    • 编辑:**

我刚刚发现,只要Image**(绿色方块)GeometryReader(红色方块)重叠,并且点击点、长按点和拖动的起点都在重叠区域内,我的自定义手势就可以工作。

fae0ux8s

fae0ux8s1#

问题解决,与SwiftUI无关:
如果在上面的代码示例中liftOff0,则绿色的ViewImage)和红色的ViewGeometryReader)在屏幕上始终具有相同的位置。如果点击绿色View,则点击位置将转发到自定义手势。由于红色View在屏幕上具有相同的位置,红色的View处理命中。
然而,如果liftOff大于绿色View和红色Viewframe大小,则两者在屏幕上不重叠。如果现在轻击绿色View,则命中位置被转发到不与绿色View重叠的红色View,即红色View未被命中。并且该命中被转发到绿色View之后的下一个View,该ViewMap本身,因此不触发定制手势,而是触发系统手势。
在上面的代码中,通过添加第3行作为GeometryReader的最后一个视图修饰符,可以很容易地检查这一点。

相关问题