首页 > 解决方案 > 不知道如何在 SwiftUI (Xcode 12.4) 中打开地图

问题描述

我刚开始在 Xcode 中编程,有些事情对我来说似乎还是有点难以理解。我在 medium.com 上找到了一个带有代码的教程,以使用 MapKit 实现当前用户位置。获取用户位置并将其显示在地图上的代码写在 MapViewController.swift 文件和类中,如下所示。

import Foundation
import UIKit
import MapKit
import CoreLocation

class MapViewController: UIViewController, CLLocationManagerDelegate {
    
    let mapView = MKMapView()
    let locationManager = CLLocationManager()
    
    override func viewDidLoad() {
        super.viewDidLoad()
        setupMapView()
        checkLocationServices()
        // Do any additional setup after loading the view.
    }
    
    func setupMapView() {
        view.addSubview(mapView)
        mapView.translatesAutoresizingMaskIntoConstraints = false
        mapView.topAnchor.constraint(equalTo: view.topAnchor).isActive = true
        mapView.bottomAnchor.constraint(equalTo: view.bottomAnchor).isActive = true
        mapView.rightAnchor.constraint(equalTo: view.safeAreaLayoutGuide.rightAnchor).isActive = true
        mapView.leftAnchor.constraint(equalTo: view.safeAreaLayoutGuide.leftAnchor).isActive = true 
    }
    
    func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
        guard let location = locations.last else { return }
        let region = MKCoordinateRegion.init(center: location.coordinate, latitudinalMeters: 4000, longitudinalMeters: 4000)
        mapView.setRegion(region, animated: true)
    }
    
    func checkLocalAuthorization() {
        switch CLLocationManager.authorizationStatus() {
        case .authorizedWhenInUse:
            mapView.showsUserLocation = true
            followUserLocation()
            locationManager.startUpdatingLocation()
            break
        case .denied:
            // Show alert
            break
        case .notDetermined:
            locationManager.requestWhenInUseAuthorization()
        case .restricted:
            // Show alert
            break
        case .authorizedAlways:
            break
        @unknown default:
        fatalError()
        }
    }
    
    func checkLocationServices() {
        if CLLocationManager.locationServicesEnabled() {
            setupLocationManager()
            checkLocalAuthorization()
        } else {
            // user did not turn it on
        }
    }
    
    func followUserLocation() {
        if let location = locationManager.location?.coordinate {
            let region = MKCoordinateRegion.init(center: location, latitudinalMeters: 4000, longitudinalMeters: 4000)
            mapView.setRegion(region, animated: true)
        }
    }
    
    func locationManager(_ manager: CLLocationManager, didChangeAuthorization status: CLAuthorizationStatus) {
        checkLocalAuthorization()
    }
    
    func setupLocationManager() {
        locationManager.delegate = self
        locationManager.desiredAccuracy = kCLLocationAccuracyBest
    }

}

问题是我不知道如何运行代码以使地图可见。当我在 ContentView.swift 中调用 MapViewController() 类时,如下所示,我收到错误“属性'body'的返回类型要求'MapViewController'符合'View'”和“静态方法'buildBlock'需要'MapViewController'符合‘观点’”。有人可以解释我如何修复错误并只查看地图吗?非常感谢提前

import SwiftUI
import UIKit
import CoreLocation
import MapKit

struct ContentView: View {
var body: some View {
    MapViewController()
    }
}

struct ContentView_Previews: PreviewProvider {
    static var previews: some View {
        ContentView()
    }
}

标签: xcodeswiftuimapkitmkmapviewxcode12

解决方案


您将需要一个 UIViewControllerRepresentable:

struct MapViewRepresentable: UIViewControllerRepresentable {
    func makeUIViewController(context: Context) -> some UIViewController {
        return MapViewController()
    }
    
    func updateUIViewController(_ uiViewController: UIViewControllerType, context: Context) {
    }
}


struct ContentView: View {
    var body: some View {
        MapViewRepresentable() //<< here use your UIViewControllerRepresentable
    }
}

推荐阅读