如何在SwiftUI地图视图中将点击手势转换为坐标? [英] How to convert tap gesture to coordinate in a SwiftUI Map view?
本文介绍了如何在SwiftUI地图视图中将点击手势转换为坐标?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!
问题描述
我正在尝试从MapKit
将MapAnnotation
项添加到我的Map()
视图。
如果您在文本字段中手动添加坐标,则一切正常,但我找不到通过点击地图来添加坐标的方法。
我在Internet上阅读了很多,但没有找到有关onTap()
映射事件处理的任何信息。
到目前为止,我的地图视图是这样的:
struct MyMap : View {
@State private var myRegion:MKCoordinateRegion = {
var newRegion = MKCoordinateRegion()
newRegion.center.latitude = 53.7576508
newRegion.center.longitude = -11.1811597
newRegion.span.latitudeDelta = 0.1
newRegion.span.longitudeDelta = 0.1
return newRegion
}()
@State private var annotationItems : [Annotation] = [
Annotation(name: "Pin1", description: "myDescription", coordinate: CLLocationCoordinate2D(latitude: 123.7576508, longitude: -7.2373215))
]
var body: some View {
ZStack {
Map(coordinateRegion: self.$myRegion, interactionModes: .all, annotationItems: annotationItems){ item in
MapAnnotation(coordinate: item.coordinate){
PinView(pin: item)
}
}
.edgesIgnoringSafeArea(.all)
}
}
}
有没有办法获取用户在地图上点击的位置的坐标?
推荐答案
执行此操作的唯一纯SwiftUI方式将阻止地图的一个或多个内置手势。
它是DragGesture
和一些数学的组合,将手势的位置转换为视图和地图之间的比率,然后根据可见跨度获得坐标。
import SwiftUI
import MapKit
struct TappableMapView: View {
@State var region: MKCoordinateRegion = .init(center: .init(latitude: 37.8199, longitude: -122.4783 ), latitudinalMeters: 500, longitudinalMeters: 500)
@State var locations: [CLLocationCoordinate2D] = []
@State var location: CGPoint = .zero
var body: some View {
VStack{
GeometryReader{ geo in
ZStack{
Map(coordinateRegion: $region, annotationItems: locations, annotationContent: {location in
MapAnnotation(coordinate: location){
Image(systemName: "circle.fill")
.resizable()
.foregroundColor(.red)
.frame(width: 50, height: 50, alignment: .center)
}
}) .simultaneousGesture(
DragGesture(minimumDistance: 0, coordinateSpace: .local).onEnded({ value in
location = value.location
//Figure out how the postion relates to the view %/ratio
let xPer = location.x/(geo.size.width)
let yPer = location.y/(geo.size.height)
//Multiply the span by the postion ratio
let lonDel = region.span.longitudeDelta * xPer
let latDel = region.span.latitudeDelta * yPer
//Get the start
let stLat = region.center.latitude + region.span.latitudeDelta/2
let stLon = region.center.longitude - region.span.longitudeDelta/2
//Add the span/ratio to the start
let loc = CLLocationCoordinate2D(latitude: stLat - latDel, longitude: stLon + lonDel)
locations.append(loc)
})
)
}
}
}
}
}
struct TappableMapView_Previews: PreviewProvider {
static var previews: some View {
TappableMapView()
}
}
它的用途非常有限,因为Map
中的DragGesture
被自定义的DragGesture
覆盖。当翻译不是零时,您可以尝试补偿并更改region
,如上面的if else
所示,但它不是实时更新。
第2部分
执行此操作的另一种方法是使用地图注释模式,其中地图手势将被禁用并替换为自定义手势。
import SwiftUI
import MapKit
struct TappableMapView: View {
@State var region: MKCoordinateRegion = .init(center: .init(latitude: 37.8199, longitude: -122.4783 ), latitudinalMeters: 500, longitudinalMeters: 500)
@State var locations: [CLLocationCoordinate2D] = []
@State var location: CGPoint = .zero
@State var gestureMask: GestureMask = .subviews
var body: some View {
VStack{
//Switch between gestures
Button("(gestureMask == .subviews ? "place annotaion mode":"map gesture mode")", action: {
gestureMask = (gestureMask == .subviews ? .gesture: .subviews)
})
GeometryReader{ geo in
ZStack{
Map(coordinateRegion: $region, annotationItems: locations, annotationContent: {location in
MapAnnotation(coordinate: location){
Image(systemName: "circle.fill")
.resizable()
.foregroundColor(.red)
.frame(width: 50, height: 50, alignment: .center)
}
})
.gesture(
DragGesture(minimumDistance: 0, coordinateSpace: .local)
.onEnded({ value in
location = value.location
//Figure out how the postion relates to the view %/ratio
let xPer = location.x/(geo.size.width)
let yPer = location.y/(geo.size.height)
//Multiply the span by the postion ratio
let lonDel = region.span.longitudeDelta * xPer
let latDel = region.span.latitudeDelta * yPer
//Get the start
let stLat = region.center.latitude + region.span.latitudeDelta/2
let stLon = region.center.longitude - region.span.longitudeDelta/2
//Add the span/ratio to the start
let loc = CLLocationCoordinate2D(latitude: stLat - latDel, longitude: stLon + lonDel)
locations.append(loc)
})
, including: gestureMask)
//The mask is applied here
}
}
}
}
}
struct TappableMapView_Previews: PreviewProvider {
static var previews: some View {
TappableMapView()
}
}
这篇关于如何在SwiftUI地图视图中将点击手势转换为坐标?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!
查看全文