在swiftUI映射中将标注添加到Pin



我正在用swift开发我的第一个地图应用程序,有点卡住了。我已经走到了这一步,但我不知道当我点击别针时如何让胼胝出现。我读过关于使用.onTapGesture的文章,当我这样做的时候,可以在控制台中打印出来,但我有点迷失了在点击地图上的点时显示一个标注。有人能给我指明正确的方向吗,甚至告诉我我现有的代码是否可以使用callout吗?

import MapKit
import SwiftUI
let mapView = MKMapView()
struct ContentView: View {
@State private var locations: [Location] = []
@State private var coordinateRegion = MKCoordinateRegion(
center: CLLocationCoordinate2D(latitude: 32.605, longitude: -85.4875),
span: MKCoordinateSpan(latitudeDelta: 0.013, longitudeDelta: 0.013)
)

@State private var showTitle = true


var body: some View {
Text("Auburn Campus Tour").font(.title)

Map(
coordinateRegion: $coordinateRegion,
showsUserLocation: true, annotationItems: locations
) {location in
MapAnnotation(
coordinate: CLLocationCoordinate2D(
latitude: location.latitude,
longitude: location.longitude
)
) {
VStack {
Image("au")
.resizable()
.edgesIgnoringSafeArea(.top)
.frame(width: 35, height: 30)
Text(location.name)
.font(.system(size: 12))
.bold()
}.onTapGesture {
//                AssetAnnotationView(au)
}
}
}
.onAppear(perform: readFile)
.onAppear{
MKMapView.appearance().mapType = .standard
MKMapView.appearance().showsPointsOfInterest = false
print("Annotations Loaded From File")
print("latitude: 32.60, longitude: -85.4875")


}
}

private func readFile() {
if let url = Bundle.main.url(forResource: "auburn", withExtension: "json"),
let data = try? Data(contentsOf: url) {
let decoder = JSONDecoder()
if let jsonData = try? decoder.decode(JSONData.self, from: data) {
self.locations = jsonData.locations
}
}
}

struct JSONData: Decodable {
let locations: [Location]
}

struct AssetAnnotationView: View {
var image: UIImage
var body: some View {
Image(uiImage: image)
.resizable()
.aspectRatio(contentMode: .fill)
.frame(width: 100, height: 100)
.cornerRadius(3.0)
.padding(4)
}
}
}
struct Location: Decodable, Identifiable {
let id: Int
let name: String
let latitude: Double
let longitude: Double
let desc: String
}
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView()
}

}

最简单的方法是为您的pin创建一个视图结构。然后你可以把它放在适当的位置。

这是针的视图示例:

@State private var showCallout = false
let title: String
let subtitle: String?
let color: UIColor
@Binding var isSelected: Bool?

init(title: String, subtitle: String? = nil, color: UIColor, isSelected: Binding<Bool?> = .constant(nil)) {
self.title = title
self.subtitle = subtitle
self.color = color
self._isSelected = isSelected
}

var body: some View {
VStack(spacing: 0) {
VStack {
Text(title)
.font(.callout)
.padding(5)

Text(subtitle ?? "")
.font(.callout)
.padding(5)
.opacity(showCallout && (subtitle != nil) ? 1 : 0)
}
.background(Color(.white))
.cornerRadius(10)
.opacity(showCallout ? 1 : 0)

Image(systemName: "exclamationmark.circle.fill")
.font(.title)
.foregroundColor(Color(uiColor: color))

Image(systemName: "arrowtriangle.down.fill")
.font(.caption)
.foregroundColor(Color(uiColor: color))
.offset(x: 0, y: -5)
}
.onTapGesture {
showCallout.toggle()
}
.onLongPressGesture {
if let _ = isSelected {
self.isSelected!.toggle()
}
}
}
}

你会这样使用它:

Map(
coordinateRegion: $coordinateRegion,
showsUserLocation: true, annotationItems: locations
) {location in
MapAnnotation(
coordinate: CLLocationCoordinate2D(
latitude: location.latitude,
longitude: location.longitude
)
) {
MapPin(title: location.name, subtitle: location.desc, color: Color.red)
}

这将在点击时显示标注,并且作为奖励,为长按选择注释提供绑定。

最新更新