微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

SwiftUI:如何将 NavigationLink 放入 MapPin 或 MapMarker

如何解决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
        }
        
    }
    
}

我的 ContentView 显示地图和显示注释

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 举报,一经查实,本站将立刻删除。