如何解决SwiftUI:如何将 NavigationLink 放入 MapPin 或 MapMarker
我已经解码了我的 JSON API 并成功地使用 MapAnnotations
在地图上显示了位置,然后输入 NavigationLink
以查看其详细信息。但是不知何故,当我缩小地图以查看所有标记的位置时,突然间我的视图在模拟器和真正的 iPhone 8 上变得非常滞后(可能是因为我在地图上有 100 多个注释?)。然后我尝试使用 MapMarker
并且视图变得更加流畅,但问题是现在我不能将 NavigationLink
放在 MapMarker
上以及 MapPin
。是否有一种正确的方法可以在地图和 NavigationLink
上显示标记/注释而不会造成视图滞后?
这是我的 LocationManager 代码,用于跟踪用户的位置
import Foundation
import CoreLocation
class LocationManager: NSObject,ObservableObject {
private let locationManager = CLLocationManager()
@Published var location: CLLocation?
override init() {
super.init()
locationManager.desiredAccuracy = kCLLocationAccuracyBest
locationManager.distanceFilter = kCLdistanceFilterNone
locationManager.requestAlwaysAuthorization()
locationManager.startUpdatingLocation()
locationManager.delegate = self
}
}
extension LocationManager: CLLocationManagerDelegate {
func locationManager(_ manager: CLLocationManager,didUpdateLocations locations: [CLLocation]) {
guard let location = locations.last else { return }
locationManager.stopUpdatingLocation()
dispatchQueue.main.async {
self.location = location
}
}
}
import SwiftUI
import MapKit
import Combine
struct ContentView: View {
var body: some View {
NavigationView{
ServiceLocation()
}
}
}
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView()
}
}
extension MKCoordinateRegion {
static var defaultRegion: MKCoordinateRegion {
MKCoordinateRegion(center: CLLocationCoordinate2D.init(latitude: -0.789275,longitude: 113.921327),latitudinalMeters: 5000,longitudinalMeters: 5000)
}
}
//MARK: MAP VIEW
struct ServiceLocation: View{
@State var serviceLocations: [ServiceLocationjsON] = []
@Observedobject private var locationManager = LocationManager()
@State private var region = MKCoordinateRegion.defaultRegion
@State private var cancellable: AnyCancellable?
private func setCurrentLocation() {
cancellable = locationManager.$location.sink { location in
region = MKCoordinateRegion(center: location?.coordinate ?? CLLocationCoordinate2D(),latitudinalMeters: 20000,longitudinalMeters: 20000)
}
}
var body: some View{
GeometryReader{ geometry in
vstack{
if locationManager.location != nil {
Map(coordinateRegion: $region,interactionModes: .all,showsUserLocation: true,userTrackingMode: .none,annotationItems: serviceLocations) { location in
MapAnnotation(coordinate: CLLocationCoordinate2D(latitude: location.LATITUDE,longitude: location.LONGITUDE)){
NavigationLink(destination: serviceLocationDetail(serviceLocations: location)){
Image(systemName: "mappin")
.resizable()
.scaledToFit()
.frame(width: geometry.size.width / 15,height: geometry.size.height / 15)
}
}
}
} else {
vstack{
Spacer()
ProgressView()
Spacer()
}
}
}.onAppear{
setCurrentLocation()
getServiceLocation(url: "https://my.api.mockaroo.com/latlong.json?key=e57d0e40"){ (serviceLocations) in
self.serviceLocations = serviceLocations
}
}
.navigationTitle("Service")
.navigationBarTitledisplayMode(.inline)
}
}
}
//MARK: DETAIL VIEW
struct serviceLocationDetail: View{
var serviceLocations: ServiceLocationjsON
var body: some View{
vstack{
if serviceLocations.DEALER_NAME.isEmpty{
vstack{
Spacer()
ProgressView()
Spacer()
}
}else{
vstack(alignment: .leading,spacing: 10){
Text(serviceLocations.DEALER_NAME)
.fontWeight(.medium)
.padding(.leading,10)
Text(serviceLocations.DEALER_ADDRESS)
.padding(.leading,10)
HStack(spacing: 5){
Image(systemName: "phone.fill")
Text(serviceLocations.PHONE)
}.padding(.leading,10)
Spacer()
}.navigationBarTitle(serviceLocations.DEALER_NAME)
}
}
Spacer()
}
}
//MARK: JSON MODEL
struct ServiceLocationjsON: Identifiable,Decodable{
var id: Int
var LATITUDE: Double
var LONGITUDE: Double
var DEALER_NAME: String
var DEALER_ADDRESS: String
var DEALER_PICTURE: String
var PHONE: String
}
//MARK: DECODE JSON MODEL
func getServiceLocation(url: String,completion: @escaping ([ServiceLocationjsON])->()){
let session = URLSession(configuration: .default)
session.dataTask(with: URL(string: url)!){ (data,_,err) in
if err != nil{
print(err!.localizedDescription)
return
}
do{
let serviceLocations = try
JSONDecoder().decode([ServiceLocationjsON].self,from: data!)
completion(serviceLocations)
}
catch{
print(error)
}
}.resume()
}
使用 Xcode 12 和 Swift 5 构建
解决方法
没关系,我刚刚解决了它。我只需要将 coordinateRegion: $region
更改为 coordinateRegion: .constant(region)
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。