HowTo - Displaying Maps in a View with Swift 2.0

Published on

Get weekly handpicked updates on Swift and SwiftUI!

In Swift 2.0, Apple has added MapKit, making it very easy for developers to incorporate the necessary map elements in a View.

Swift
import SwiftUI
import MapKit

struct MapView: View{
    // Set initial display area
    @State private var region: MKCoordinateRegion = MKCoordinateRegion(
        center: CLLocationCoordinate2D(latitude: 38.92083, longitude: 121.63917),
        span: MKCoordinateSpan(latitudeDelta: 0.5, longitudeDelta: 0.5)
    )
    
    // Set to continuously track user's current location
    @State private var trackmode = MapUserTrackingMode.follow
    
    // Set marker point information
    let dots: [MapDot] = [
        MapDot(title: "point1",
               coordinate: CLLocationCoordinate2D(latitude: 38.92083, longitude: 121.63917),
               color: .red),
        MapDot(title: "point2",
               coordinate: CLLocationCoordinate2D(latitude: 38.92183, longitude: 121.62717),
               color: .blue)
    ]
    
    @StateObject var store = Store()
    
    var body: some View {
        ZStack(alignment: .bottom){
            Map(coordinateRegion: $region,
                interactionModes: .all, // .pan, .zoom, .all
                showsUserLocation: true, // Show user's current location
                userTrackingMode: $trackmode, // Update user location
                annotationItems: dots // Marker point data
            ){ item in
                // Marker point display, can also use built-in MapPin, but MapPin can't respond to user input
                MapAnnotation(coordinate: item.coordinate){
                    // Uncertain if it's a bug, but currently Text cannot be displayed in iOS, can be displayed in macOS
                    Label(item.title, systemImage: "star.fill")
                        .font(.body)
                        .foregroundColor(item.color)
                        .onTapGesture {
                            print(item.title)
                        }
                }
            }
        }
        .edgesIgnoringSafeArea(.all)
    }
}

// Marker point data, must conform to Identifiable
struct MapDot: Identifiable{
    let id = UUID()
    let title: String
    let coordinate: CLLocationCoordinate2D
    let color: Color
}

class Store: ObservableObject {
    let manager = CLLocationManager()
    init() {
        // Request location access permission. Need to set Privacy - Location When In Use Usage Description in plist
        // If displaying current user location is not needed, then no need to request permission
        #if os(iOS)
            manager.requestWhenInUseAuthorization()
        #endif
    }
}
Weekly Swift & SwiftUI insights, delivered every Monday night. Join developers worldwide.
Easy unsubscribe, zero spam guaranteed