100 Days of SwiftUI(DAY 70(Project14 part 3))

注釈を追加して操作できるマップビューを構築します。
スティーブジョブズ氏は次のように述べています。デザインは見た目や雰囲気だけではありません。デザインはそれがどのように機能するかです。」

SwiftUIを備えた高度なMKMapView
Advanced MKMapView with SwiftUI

import SwiftUI
import MapKit

struct MapView: UIViewRepresentable {
    //ContentViewのcenterCoordinateにバインディング
    @Binding var centerCoordinate: CLLocationCoordinate2D
    
    var annotations: [MKPointAnnotation]
    
    func makeUIView(context: Context) -> MKMapView {
        let mapView = MKMapView()
        mapView.delegate = context.coordinator
        return mapView
    }

    func updateUIView(_ view: MKMapView, context: Context) {
        if annotations.count != view.annotations.count {
            view.removeAnnotations(view.annotations)
            view.addAnnotations(annotations)
        }
    }

    func makeCoordinator() -> Coordinator {
        Coordinator(self)
    }
    //-------------------------------------------
    class Coordinator: NSObject, MKMapViewDelegate {
        var parent: MapView

        init(_ parent: MapView) {
            self.parent = parent
        }
        func mapViewDidChangeVisibleRegion(_ mapView: MKMapView) {
            parent.centerCoordinate = mapView.centerCoordinate
        }
    }
}

extension MKPointAnnotation {
    static var example: MKPointAnnotation {
        let annotation = MKPointAnnotation()
        annotation.title = "London"
        annotation.subtitle = "Home to the 2012 Summer Olympics."
        annotation.coordinate = CLLocationCoordinate2D(latitude: 51.5, longitude: -0.13)
        return annotation
    }
}
struct MapView_Previews: PreviewProvider {
    static var previews: some View {
       MapView(centerCoordinate: .constant(MKPointAnnotation.example.coordinate), annotations: [MKPointAnnotation.example])
    }
}


import SwiftUI
import MapKit


struct ContentView: View {
    @State private var centerCoordinate = CLLocationCoordinate2D()
    @State private var locations = [MKPointAnnotation]()
    
    
    var body: some View {
        ZStack {
            //引数として、
            MapView(centerCoordinate: $centerCoordinate, annotations: locations)
                .edgesIgnoringSafeArea(.all)
            Circle()
                .fill(Color.blue)
                .opacity(0.3)
                .frame(width: 32, height: 32)
            VStack {
                Spacer()
                HStack {
                    Spacer()
                    Button(action: {
                        // create a new location
                        let newLocation = MKPointAnnotation()
                        newLocation.coordinate = self.centerCoordinate
                        self.locations.append(newLocation)
                    }) {
                        Image(systemName: "plus")
                    }
                    .padding()
                    .background(Color.black.opacity(0.75))
                    .foregroundColor(.white)
                    .font(.title)
                    .clipShape(Circle())
                    .padding(.trailing)
                }
            }
        }
    }
}

MKMapViewアノテーションのカスタマイズ
Customizing MKMapView annotations

ユーザーが場所をタップして詳細を確認し、もう一度タップしてその場所を編集できるようにします。これらすべてを実現するには、小さなSwiftUI、小さなUIKit、小さなMapKitがすべて1つにまとめられます。これは興味深い課題です。
mapView(_:viewFor:)メソッド—–>>マップピンを表すカスタムビューを提供する場合に呼び出されます。
パフォーマンスのためにビューを再利用するより高度なソリューションを使用し、さらに詳細情報を表示するためにタップできるボタンを追加します。
dequeueReusableAnnotationView(withIdentifier🙂
リサイクルされるのを待っているビューがある場合、それを取得し、必要に応じて再構成できます。そうでない場合は、戻ってnil自分でビューを作成する必要があります。
rightCalloutAccessoryViewここに、詳細情報を表示するためのボタンを配置します。