// // MapViewController.swift // Runner // // Created by Groot on 2025/5/7. // import UIKit import MapKit import Combine class MapViewController: UIViewController { required init?(coder: NSCoder) { fatalError("init(coder:) has not been implemented") } let viewModel: MapViewModel let mapView = MKMapView() private var cancellables = Set() init(viewModel: MapViewModel) { self.viewModel = viewModel super.init(nibName: nil, bundle: nil) } override func viewDidLoad() { super.viewDidLoad() setupView() setupMap() bindViewModel() } private func setupView() { mapView.translatesAutoresizingMaskIntoConstraints = false view.addSubview(mapView) NSLayoutConstraint.activate([ mapView.topAnchor.constraint(equalTo: view.topAnchor), mapView.bottomAnchor.constraint(equalTo: view.bottomAnchor), mapView.leadingAnchor.constraint(equalTo: view.leadingAnchor), mapView.trailingAnchor.constraint(equalTo: view.trailingAnchor) ]) } private func setupMap() { mapView.delegate = self mapView.showsUserLocation = true mapView.setUserTrackingMode(.follow, animated: true) } private func bindViewModel() { // 监听区域变化并更新地图 viewModel.$currentRegion .compactMap { $0 } .sink { [weak self] region in self?.mapView.setRegion(region, animated: true) } .store(in: &cancellables) viewModel.$markers .sink { [weak self] markers in self?.mapView.removeAnnotations(self?.mapView.annotations ?? []) self?.mapView.addAnnotations(markers) } .store(in: &cancellables) viewModel.$polylines .sink { [weak self] polylines in self?.mapView.removeOverlays(self?.mapView.overlays ?? []) self?.mapView.addOverlays(polylines.map({ $0.polyline })) } .store(in: &cancellables) } } extension MapViewController: MKMapViewDelegate { func mapView(_ mapView: MKMapView, viewFor annotation: MKAnnotation) -> MKAnnotationView? { var annotationView = mapView.dequeueReusableAnnotationView(withIdentifier: MapAnnotationView.identifier) as? MapAnnotationView // 如果没有可复用的视图,创建新的自定义标注视图 if annotationView == nil { annotationView = MapAnnotationView(annotation: annotation, reuseIdentifier: MapAnnotationView.identifier) } else { // 更新现有视图的标注 annotationView?.annotation = annotation } return annotationView } func mapView(_ mapView: MKMapView, didSelect view: MKAnnotationView) { guard var marker = view.annotation as? ATMapMarker else { return } viewModel.handleMarkerTap(marker: &marker) } func mapView(_ mapView: MKMapView, rendererFor overlay: MKOverlay) -> MKOverlayRenderer { let renderer = MKPolylineRenderer(overlay: overlay) renderer.lineWidth = 5 renderer.strokeColor = .blue renderer.alpha = 1 renderer.lineCap = .round renderer.lineJoin = .round return renderer } }