SwiftUI map : How to convert screen coordinates to map coordinates?

标签 swiftui draggable coordinate-transformation mapview

设置:

我正在将应用程序转换为 SwiftUI。此应用有一个带有注释的 MKMapView,可以在 map 上拖动。
我能够编写带有可拖动图像的 SwiftUI 应用程序的第一个版本。
它使用在 map 上显示为注释的 View:

struct AnnotationView: View {
    var buyLocationNameBeforeDragging: String
    @State private var isDragging = false
    @GestureState var dragAmount = CGSize.zero
    var region: MKCoordinateRegion
    
    func coordinateFrom(region: MKCoordinateRegion, dragAmount: CGSize) -> CLLocationCoordinate2D {
        let coordinate = CLLocationCoordinate2D() // How to compute this?
        return coordinate
    }
    
    var drag: some Gesture {
        DragGesture()
            .onChanged { _ in
                self.isDragging = true
            }
            .onEnded { _ in
                self.isDragging = false
                let coreDataManager = testOrPreview ? CoreDataManager.test : CoreDataManager.shared
                let newCoordinate = coordinateFrom(region: region, dragAmount: dragAmount)
                // Move the dragged place to the new coordinate
                // …
            }
            .updating($dragAmount) { value, state, transaction in
                state = value.translation
            }
    }
    
    var body: some View {
        Image("PinRed")
            .offset(dragAmount)
            .defersSystemGestures(on: .all)
            .onTapGesture {
                print("tapped")
            }
            .gesture(drag)
    }
}  

可以点击注释图钉,并在点击较长时间后将图钉拖动到新位置。

问题:

要更新我的模型,我需要 map 上拖动的端点坐标。这些应该在 func axisFrom 中计算(见上文),但我不知道如何做到这一点。
MKMapView 有例如一个函数 convert(_:toCooperativeFrom:),但 SwiftUI 的 Map 没有这样的东西。

问题:

如何进行转换?

最佳答案

问题已解决。
我第一次将 var Drag: some Gesture 转换为函数:

func drag(geo: GeometryProxy) -> some Gesture {
    DragGesture(coordinateSpace: .named("screen"))
        .onChanged { value in
            self.isDragging = true
        }
        .onEnded { _ in
            self.isDragging = false
            let coreDataManager = testOrPreview ? CoreDataManager.test : CoreDataManager.shared
            let newCoordinate = coordinateFrom(region: region, geo: geo, dragAmount: dragAmount)
            // Move the dragged place to the new coordinate
            // …
        }
        .updating($dragAmount) { value, state, transaction in
            state = value.translation
        }
}

其中 geoAnnotationView 的主体提供,并且 .coordinateSpace(name: "screen") 已应用于显示 map 的 View :

var body: some View {
    GeometryReader { geo in
        Image("PinRed")
            .offset(dragAmount)
            .defersSystemGestures(on: .all)
            .onTapGesture {
                print("Global center: \(geo.frame(in: .global).midX) x \(geo.frame(in: .global).midY)")
            }
            .gesture(drag(geo: geo))
    }
    .frame(width: 40, height: 30)
}

接下来,我使用旧的 MKMapView 将 map 坐标从屏幕坐标转换为 map 坐标:

func coordinateFrom(region: MKCoordinateRegion, geo: GeometryProxy, dragAmount: CGSize) -> CLLocationCoordinate2D {
    let mkMapView = MKMapView(frame: CGRect(x: 0, y: 0, width: UIScreen.main.bounds.size.width, height: UIScreen.main.bounds.size.height))
    mkMapView.region = region
    let frame = geo.frame(in: .global)
    let dragEndPoint = CGPoint(x: frame.origin.x + dragAmount.width, y: frame.origin.y + dragAmount.height)
    let dragEndCFoordinate = mkMapView.convert(dragEndPoint, toCoordinateFrom: mkMapView)
    return dragEndCFoordinate
}

在这里,我假设 MKMapView 和 SwiftUI Map 使用相同的坐标变换。就我而言,我没有看到任何差异。

关于SwiftUI map : How to convert screen coordinates to map coordinates?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/74762467/

相关文章:

swiftui-list - SwiftUI 列表在 @ObservedObject 更新时卡住

Jquery - 如果 'draggable div' 的大小大于 'droppable div',则不会发生 Drop 事件

javascript - 背景图像裁剪到可拖动的 div

jquery - 可拖动背景 Js 在 ie8 中不起作用

python - 是否可以将 matplotlib 注释锚定到 x 轴中的数据坐标,但锚定到 y 轴中的相对位置?

ios - 如何在不包装旧库的情况下让 OAuth2 与 SwiftUI 一起使用?

SwiftUI – 在 View 中向用户显示变量

ios - 带有系统背景颜色的列表在黑暗模式下变得困惑

c++ - 在 C++ 中使用您自己的 Matrix 类进行 OpenGL 对象旋转

python - python中的多项式变换