Reputation: 41
tldr: I try to add actions with alerts to a button in pinView and store this data (names of pins with describtion and pin icon) in UserDefaults. I have pins with MKPinAnnotationView and a button in it. I would like this button to check if user is more or less than 100 meters form the CLLocation of the pin. After clicking the button (when the user IS INSIDE 100m radius od pin location) it should show UIAlertController (otherwise it should display similar alert as below with the info that user is outside radius for example with just cancel action):
let alertController = UIAlertController(title: "Check-in!", message: "Click below to check-in", preferredStyle: UIAlertController.Style.alert)
alertController.addAction(UIAlertAction(title: "Check-In", style: UIAlertAction.Style.default, handler: { action in //HERE I WOULD LIKE TO SAVE THE NAME OF THE PIN SOMEWHERE IN UserDefaults to display it later in table view in another ViewController))
alertController.addAction(UIAlertAction(title: "Cancel", style: UIAlertAction.Style.default, handler: { action in //close alert and do nothing))
Here is my code:
import UIKit
import MapKit
class ViewController: UIViewController, MKMapViewDelegate{
let locationManager = CLLocationManager()
struct Szczyt {
let name: String
let opis: String
let lattitude: CLLocationDegrees
let longtitude: CLLocationDegrees
var coordinate: CLLocationCoordinate2D {
.init(latitude: lattitude, longitude: longtitude)
}
}
@IBOutlet weak var mapView: MKMapView!
@IBAction func mapTypeSegmentSelected(_ sender: UISegmentedControl) {
switch sender.selectedSegmentIndex {
case 0:
mapView.mapType = .standard
case 1:
mapView.mapType = .satellite
default:
mapView.mapType = .hybrid
}
}
private(set) var circles: [MKCircle]!
let szczyty = [Szczyt(name: "one", opis: "describtion", lattitude: 53.865061725039226, longtitude: 17.708595782487315),
Szczyt(name: "two", opis: "describtion2", lattitude: 55.893874478583854, longtitude: 24.896341184611302),
Szczyt(name: "Skrzyczne", opis: "describtion3", lattitude: 49.685059170137386, longtitude: 19.030076144463138)]
override func viewDidLoad() {
super.viewDidLoad()
mapView.register(MKMarkerAnnotationView.self, forAnnotationViewWithReuseIdentifier: "identifier")
checkLocationServices()
znajdzSzczytyNaMapie(szczyty)
circles = szczyty.map {
MKCircle(center: $0.coordinate, radius: 100)
}
mapView.addOverlays(circles!)
mapView.delegate = self
}
func checkLocationServices() {
if CLLocationManager.locationServicesEnabled() {
checkLocationAuthorization()
} else {
// Show alert letting the user know they have to turn this on.
}
}
func checkLocationAuthorization() {
switch CLLocationManager.authorizationStatus() {
case .authorizedWhenInUse:
mapView.showsUserLocation = true
case .denied:
break
case .notDetermined:
locationManager.requestWhenInUseAuthorization()
mapView.showsUserLocation = true
case .restricted:
break
case .authorizedAlways:
break
}
}
func znajdzSzczytyNaMapie(_ szczyty: [Szczyt]) {
for szczyt in szczyty {
let annotations = MKPointAnnotation()
annotations.title = szczyt.name
annotations.subtitle = szczyt.opis
annotations.coordinate = CLLocationCoordinate2D(latitude:
szczyt.lattitude, longitude: szczyt.longtitude)
mapView.addAnnotation(annotations)
}
}
let location = CLLocation()
let circleCenter = CLLocation()
//This I think is necessary for detecting if user is in 100m distance from the location - Is it good?:if location.distance(from: circleCenter) < circleRadius {
// User is inside radius 100m.
//}
func mapView(_ mapView: MKMapView, viewFor annotation: MKAnnotation) -> MKAnnotationView? {
guard !(annotation is MKUserLocation) else { return nil }
mapView.delegate = self
let annotationView = MKPinAnnotationView(annotation: annotation, reuseIdentifier: String(annotation.hash))
let identifier = "identifier"
annotationView.canShowCallout = true
guard let annotationView = mapView.dequeueReusableAnnotationView(withIdentifier: identifier, for: annotation) as? MKMarkerAnnotationView else { return nil }
let rightButton = UIButton(type: .contactAdd)
rightButton.tag = annotation.hash
annotationView.canShowCallout = true
annotationView.rightCalloutAccessoryView = rightButton
//HERE IS THIS BUTTON called rightButton that I need action with alerts.
switch annotation.title!! {
case "one":
annotationView.markerTintColor = UIColor(red: 0.86, green: 0.99, blue: 0.79, alpha: 1.00)
annotationView.glyphImage = UIImage(named: "one_pic")
case "two":
annotationView.markerTintColor = UIColor(red: 0.80, green: 0.98, blue: 0.73, alpha: 1.00)
annotationView.glyphImage = UIImage(named: "two_pic"")
case "Skrzyczne":
annotationView.markerTintColor = UIColor(red: 0.02, green: 0.61, blue: 0.69, alpha: 1.00)
annotationView.glyphImage = UIImage(named: "three_pic"")
default:
annotationView.markerTintColor = UIColor.green
annotationView.glyphImage = UIImage(named: "default")
}
return annotationView
}
func mapView(_ mapView: MKMapView, rendererFor overlay: MKOverlay) -> MKOverlayRenderer {
let circleRenderer = MKCircleRenderer(overlay: overlay)
circleRenderer.strokeColor = UIColor.green
circleRenderer.fillColor = UIColor.green
circleRenderer.alpha = 0.3
circleRenderer.lineWidth = 1.0
return circleRenderer
}
}
For these stored thata with names I've created second ViewController to store it with Table View.
If something is not understandable, please ask :) Thank you in advance.
Upvotes: 0
Views: 54