#ios #swift #uibutton #userdefaults #mkpinannotationview
Вопрос:
tldr: Я пытаюсь добавить действия с предупреждениями к кнопке в pinView и сохранить эти данные (имена контактов с описанием и значком pin-кода) в UserDefaults. У меня есть булавки с MKPinAnnotationView и кнопкой в нем. Я хотел бы, чтобы эта кнопка проверяла, находится ли пользователь более или менее чем в 100 метрах от места размещения pin-кода. После нажатия кнопки (когда пользователь находится В радиусе 100 м от местоположения pin-кода) он должен показать UIAlertController (в противном случае он должен отображать аналогичное предупреждение, как показано ниже, с информацией о том, что пользователь находится за пределами радиуса, например, с помощью простого действия отмены):
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))
Вот мой код:
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
}
}
Для этих сохраненных данных с именами я создал второй ViewController, чтобы сохранить их в виде таблицы.
Если что-то непонятно, пожалуйста, спросите 🙂 Заранее спасибо.
Комментарии:
1. «100 метров образуют КЛОкокацию штифта»? «когда пользователь НАХОДИТСЯ ВНУТРИ местоположения пин-кода радиусом 100 м», что это за вещь, которую вы так называете местоположением пин-кода радиусом 100 м?
2. @Эль Помидор
circles = szczyty.map { MKCircle(center: $0.coordinate, radius: 100)
Дело в том, что его можно использовать с оператором if, который я прокомментировал.3. @El Tomato есть какие-нибудь предложения? Заранее спасибо.
4. Я не смогу вам помочь, пока вы не исправите свои опечатки.