Here you are my solutions to the Silver and Golden Challenges as they are tightly connected.
Show here only the source code related to these solutions.
import MapKit
import CoreLocation
class MapViewController: UIViewController, CLLocationManagerDelegate {
var mapView: MKMapView!
let locationManager = CLLocationManager()
var pins: [MKAnnotation]?
var pinItem = 1
override func loadView() {
super.loadView()
mapView = MKMapView()
mapView.showsUserLocation = false
view = mapView
let locationButton = UIButton(type: .system)
locationButton.backgroundColor = UIColor.clear
let image = UIImage(named: "Tag.png")
locationButton.setImage(image, for: .normal)
locationButton.sizeToFit()
locationButton.addTarget(self, action: #selector(showUserLocation), for: .touchUpInside)
locationButton.translatesAutoresizingMaskIntoConstraints = false
view.addSubview(locationButton)
let bottomLocationButtonConstrain = locationButton.bottomAnchor.constraint(equalTo: bottomLayoutGuide.topAnchor, constant: -16)
bottomLocationButtonConstrain.isActive = true
let trailingLocationButtonConstrain = locationButton.trailingAnchor.constraint(equalTo: magins.trailingAnchor)
trailingLocationButtonConstrain.isActive = true
let pinsButton = UIButton(type: .system)
pinsButton.backgroundColor = UIColor.clear
let pinsImage = UIImage(named: "Pin.png")
pinsButton.setImage(pinsImage, for: .normal)
pinsButton.sizeToFit()
pinsButton.addTarget(self, action: #selector(showPins), for: .touchUpInside)
pinsButton.translatesAutoresizingMaskIntoConstraints = false
view.addSubview(pinsButton)
let bottomPinsButtonConstrain = pinsButton.bottomAnchor.constraint(equalTo: locationButton.topAnchor, constant: -16)
bottomPinsButtonConstrain.isActive = true
let trailingPinsButtonConstrain = pinsButton.trailingAnchor.constraint(equalTo: magins.trailingAnchor)
trailingPinsButtonConstrain.isActive = true
}
//MARK: - MKMapViewDelegate
func requestStatus() -> Bool {
let authStatus = CLLocationManager.authorizationStatus()
if authStatus == .notDetermined {
locationManager.requestWhenInUseAuthorization()
return true
}
if authStatus == .denied || authStatus == .restricted {
showLocationServicesDeniedAlert()
return true
}
return false
}
@objc func showUserLocation() {
if requestStatus() {
return
}
if let pins = pins {
mapView.removeAnnotations(pins)
}
mapView.userTrackingMode = .follow
mapView.showsUserLocation = true
}
@objc func showPins() {
if requestStatus() {
return
}
if pins == nil {
pins = [MKAnnotation]()
mapView.showsUserLocation = false
pins!.append(mapView.userLocation)
let bacotaPin = Pin(title: "Bacota Bay", coordinate: CLLocationCoordinate2D(latitude: 48.585714, longitude: 26.998488), subtitle: "Love to come here")
pins!.append(bacotaPin)
let maliyivtsiPin = Pin(title: "Maliyivtsi", coordinate: CLLocationCoordinate2D(latitude: 48.991991, longitude: 26.996249), subtitle: "Nice place to visit")
pins!.append(maliyivtsiPin)
mapView.addAnnotation(pins![0] as MKAnnotation)
mapView.userTrackingMode = .follow
} else {
mapView.showsUserLocation = false
if pinItem == 3 {
pinItem = 0
}
mapView.removeAnnotations(pins!)
mapView.addAnnotation(pins![pinItem])
let region = MKCoordinateRegionMakeWithDistance(pins![pinItem].coordinate, 1000, 1000)
mapView.setRegion(mapView.regionThatFits(region), animated: true)
pinItem += 1
}
}
func showLocationServicesDeniedAlert() {
let alertController = UIAlertController(title: "Location Services Disabled", message: "Please enable location services for this app in Settings", preferredStyle: .alert)
let okAction = UIAlertAction(title: "OK", style: .default, handler: nil)
alertController.addAction(okAction)
present(alertController, animated: true, completion: nil)
}
}
class Pin: NSObject, MKAnnotation {
var title: String?
var coordinate: CLLocationCoordinate2D
var subtitle: String?
init(title: String?, coordinate: CLLocationCoordinate2D, subtitle: String?) {
self.title = title
self.coordinate = coordinate
self.subtitle = subtitle
}
}