[英]SwiftUI Map: How to convert screen coordinates to map coordinates?
Setup:设置:
I am converting an app to SwiftUI. This app had an MKMapView
with annotations that could be dragged on the map.我正在将一个应用程序转换为 SwiftUI。这个应用程序有一个带有注释的
MKMapView
,可以在 map 上拖动。
I was able to write a first version of the SwiftUI app with a draggable image.我能够编写带有可拖动图像的 SwiftUI 应用程序的第一个版本。
It uses a View
that is displayed as annotation on the map:它使用在 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)
}
}
It is possible to tap the annotation pin, and - after tapping longer - to drag the pin to a new location.可以点击注释图钉,并且 - 在点击更长时间后 - 将图钉拖动到新位置。
Problem:问题:
To update my model, I need the endpoint coordinates of the drag on the map. These should be computed in func coordinateFrom
(see above), but I have no idea how to do this.要更新我的 model,我需要 map 上拖动的端点坐标。这些应该在
func coordinateFrom
中计算(见上文),但我不知道如何执行此操作。
MKMapView
has eg a function convert(_:toCoordinateFrom:)
, but SwiftUI's Map
has nothing like this. MKMapView
有一个 function convert(_:toCoordinateFrom:)
,但是 SwiftUI 的Map
没有这样的东西。
Question:题:
How to do the conversion?如何进行转换?
Problem solved.问题解决了。
I 1st converted var drag: some Gesture
to a function:我第一次转换
var drag: some Gesture
到 function:
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
}
}
where geo
is supplied by the body of the AnnotationView
, and .coordinateSpace(name: "screen")
has been applied to the view displaying the map:其中
geo
由AnnotationView
的主体提供,并且.coordinateSpace(name: "screen")
已应用于显示 map 的视图:
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)
}
Next, I converted the map coordinates from screen coordinates to map coordinates using the old MKMapView
as:接下来,我使用旧的
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
}
Here, I assume the MKMapView
and SwiftUI Map
use the same coordinate transforms.在这里,我假设
MKMapView
和 SwiftUI Map
使用相同的坐标变换。 In my case, I don't see any differences.就我而言,我没有看到任何差异。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.