// added “NSLocationWhenInUseUsageDescription$(PRODUCT_NAME) location use.” in the Info.plist
// it only works with a real iOS device connected
import UIKit
import MapKit
class MapViewController: UIViewController, MKMapViewDelegate {
// MARK: - Properties
var mapView: MKMapView!
var locationManager = CLLocationManager() // Silver Challenge
// MARK: - UIViewController Method
override func loadView() {
mapView = MKMapView()
view = mapView
mapView.delegate = self // Silver Challenge
let segmentedControl = UISegmentedControl(items: ["Standard", "Hybrid", "Satellite"])
segmentedControl.backgroundColor = UIColor.white.withAlphaComponent(0.5)
segmentedControl.selectedSegmentIndex = 0
segmentedControl.addTarget(self, action: #selector(MapViewController.mapTypeChanged(_:)), for: .valueChanged)
segmentedControl.translatesAutoresizingMaskIntoConstraints = false
view.addSubview(segmentedControl)
let topConstraint = segmentedControl.topAnchor.constraint(equalTo: topLayoutGuide.bottomAnchor, constant: 8)
let margins = view.layoutMarginsGuide
let leadingConstraint = segmentedControl.leadingAnchor.constraint(equalTo: margins.leadingAnchor)
let trailingConstraint = segmentedControl.trailingAnchor.constraint(equalTo: margins.trailingAnchor)
topConstraint.isActive = true
leadingConstraint.isActive = true
trailingConstraint.isActive = true
/* -------------------- my add for the Silver Challenge: create a button programmatically --------------------- */
let button = UIButton(type: .system)
button.backgroundColor = UIColor.blue.withAlphaComponent(0.5)
button.setTitle("Show Location", for: .normal)
button.setTitleColor(UIColor.white, for: .normal)
button.layer.cornerRadius = 5
button.addTarget(self, action: #selector(MapViewController.buttonAction(sender:)), for: .touchUpInside)
button.translatesAutoresizingMaskIntoConstraints = false
view.addSubview(button)
let bottomConstraintBtn = button.bottomAnchor.constraint(equalTo: bottomLayoutGuide.topAnchor, constant: -10)
let marginsBtn = view.layoutMarginsGuide
let leadingConstraintBtn = button.leadingAnchor.constraint(equalTo: marginsBtn.leadingAnchor)
let trailingConstraintBtn = button.trailingAnchor.constraint(equalTo: marginsBtn.trailingAnchor)
bottomConstraintBtn.isActive = true
leadingConstraintBtn.isActive = true
trailingConstraintBtn.isActive = true
/* ------------------------------------------------------------------------------------------------------------ */
}
override func viewDidLoad() {
super.viewDidLoad()
print("MapViewController loaded its view.")
}
// MARK: - Helper Methods
func mapTypeChanged(_ segControl: UISegmentedControl) {
switch segControl.selectedSegmentIndex {
case 0:
mapView.mapType = .standard
case 1:
mapView.mapType = .hybrid
case 2:
mapView.mapType = .satellite
default:
break }
}
func buttonAction(sender: UIButton!) { // Silver Challenge
locationManager.requestWhenInUseAuthorization()
mapView.showsUserLocation = !mapView.showsUserLocation // instead of: "mapView.showsUserLocation = true"
// the statement below can replace the entire method "func mapView(_ mapView: MKMapView, didUpdate userLocation: MKUserLocation)", eventhough the effect will be different
/* mapView.userTrackingMode = .followWithHeading */ // works fine only the first time the "Show Location" button gets pressed, then the heading/compass capabilities disappear
if mapView.showsUserLocation == true {
sender.setTitle("Hide Location", for: .normal)
}
else {
sender.setTitle("Show Location", for: .normal)
}
}
// MARK: - MKMapViewDelegate Method
func mapView(_ mapView: MKMapView, didUpdate userLocation: MKUserLocation) { // Silver Challenge
let region = MKCoordinateRegionMakeWithDistance(userLocation.coordinate, 500, 500)
mapView.setRegion(region, animated: true)
}
}