如何在 SwiftUI 的新地图视图中制作可点击的图钉? [英] How do I make a clickable pin in SwiftUI's new Map view?
问题描述
我正在使用 SwiftUI 的新地图视图来显示注释的大头针,并且希望大头针在单击时显示用于编辑注释名称和描述的视图.
I'm using SwiftUI new Map view to display pins for annotations, and would like the pins, when clicked, to display a view for editing the annotation's name and description.
我尝试将 MapAnnotation 与包含带有图钉图像的按钮的视图一起使用.图像显示正确,但按钮不起作用.
I've tried to use MapAnnotation with a view that contains a button with a pin image. The image displays correctly, but the button doesn't work.
是否可以在不回退到 MKMapView 的 UIViewRepresentable 的情况下执行此操作?
Is it possible to do this without falling back to a UIViewRepresentable of MKMapView?
import SwiftUI
import MapKit
struct ContentView: View {
@State private var showingEditScreen = false
@State private var region = MKCoordinateRegion(
center: CLLocationCoordinate2D(latitude: 37.334722,
longitude: -122.008889),
span: MKCoordinateSpan(latitudeDelta: 1,
longitudeDelta: 1)
)
@State private var pins: [Pin] = [
Pin(name: "Apple Park",
description: "Apple Inc. headquarters",
coordinate: CLLocationCoordinate2D(latitude: 37.334722,
longitude:-122.008889))
]
var body: some View {
Map(coordinateRegion: $region,
interactionModes: .all,
annotationItems: pins,
annotationContent: { pin in
MapAnnotation(coordinate: pin.coordinate,
content: {
PinButtonView(pin: pin)
})
})
}
}
我的 Pin 图定义:
My Pin definition:
struct Pin: Identifiable {
let id = UUID()
var name: String
var description: String
var coordinate: CLLocationCoordinate2D
}
带有按钮和图钉图像的视图:
The view with the button and pin image:
struct PinButtonView: View {
@State private var showingEditScreen = false
@State var pin: Pin
var body: some View {
Button(action: {
showingEditScreen.toggle()
}) {
Image(systemName: "mappin")
.padding()
.foregroundColor(.red)
.font(.title)
}
.sheet(isPresented: $showingEditScreen,
content: {
EditView(pin: self.$pin)
})
}
}
编辑视图:
struct EditView: View {
@Environment(.presentationMode) var presentationMode
@Binding var pin: Pin
var body: some View {
NavigationView {
Form {
TextField("Place name", text: $pin.name)
TextField("Description", text: $pin.description)
}
.navigationTitle("Edit place")
.navigationBarItems(trailing: Button("Done") {
self.presentationMode.wrappedValue.dismiss()
})
}
}
}
推荐答案
从 XCode 12.3 开始,这似乎可以与按钮一起使用.我注意到的一个关键问题是,如果您使用偏移量,那么您的按钮可能会被放置在注释的可点击区域之外.
As of XCode 12.3 this appears to be functioning with buttons. One key gotcha that I noticed though was that if you use offsets then it's possible your buttons will be placed out of the tappable area of the annotation.
为了解决这个问题,您可以添加额外的填充来解决偏移并将其保持在可点击的范围内:
In order to counter that you can add additional padding to account for the offset and keep it within tappable bounds:
MapAnnotation(coordinate: item.placemark.coordinate) {
ZStack {
MapPinView() // My view for showing a precise pin
VStack { // A prompt with interactive option, offset by 60pt
Text("Use this location?")
HStack {
Button("Yes", action: {
print("yes")
})
Button("No", action: {
print("no")
})
}
}
.offset(x: 0, y: 60) // offset prompt so it's below the marker pin
}
.padding(.vertical, 60) // compensate for offset in tappable area of annotation. pad both the top AND the bottom to keep contents centered
}
这篇关于如何在 SwiftUI 的新地图视图中制作可点击的图钉?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!