ios - manager - swift 4 get current location
MKMapView MKPointAnnotation tap evento (3)
Añadir botón en este método
-(MKAnnotationView *)mapView:(MKMapView *)mapView viewForAnnotation:(id <MKAnnotation>)annotation
{
pinView.rightCalloutAccessoryView = [UIButton buttonWithType:UIButtonTypeDetailDisclosure];
pinView.canShowCallout = YES;
}
Then callout method
- (void)mapView:(MKMapView *)mapView annotationView:(MKAnnotationView *)view calloutAccessoryControlTapped:(UIControl *)control
{
InfoView *infoView = [[InfoView alloc]initWithNibName:@"InfoView" bundle:nil];
[self.navigationController pushViewController:infoView animated:YES];
}
Tengo una lista de anotaciones (MKPointAnnotation). Tengo un UIViewController que es para toda la vista, MKMapView implementando Controller, que creo que es útil para detectar la interacción de los usuarios con el mapa, mi propio MKPointAnnotation implementando (subclase) Controller que indica cómo mostrar la anotación.
Sin embargo, me sorprende la detección del evento tap por parte del usuario.
Google me dijo que tengo que hacer algo implementando la siguiente función.
- (void)mapView:(MKMapView *)mapView annotationView:(MKAnnotationView *)view calloutAccessoryControlTapped:(UIControl *)control
y también que tengo que implementar esto en alguna clase que implementa el MapViewDelegate (Protocolo).
Pero estoy todo confundido e incapaz de seguir adelante. ¿Alguien puede decirme dónde hacer qué?
Lo siento por todo el alboroto!
Ejemplo de Robs para Swift 3:
class MapViewController: UIViewController
{
override func viewDidLoad()
{
super.viewDidLoad()
// Create map view in storyboard
view.delegate = self
}
}
extension MapViewController: MKMapViewDelegate
{
func mapView(_ mapView: MKMapView, viewFor annotation: MKAnnotation) -> MKAnnotationView?
{
let annotationView = MKPinAnnotationView(annotation: annotation, reuseIdentifier: "annotationView")
annotationView.canShowCallout = true
annotationView.rightCalloutAccessoryView = UIButton.init(type: UIButtonType.detailDisclosure)
return annotationView
}
func mapView(_ mapView: MKMapView, annotationView view: MKAnnotationView, calloutAccessoryControlTapped control: UIControl)
{
guard let annotation = view.annotation else
{
return
}
let urlString = "http://maps.apple.com/?sll=/(annotation.coordinate.latitude),/(annotation.coordinate.longitude)"
guard let url = URL(string: urlString) else
{
return
}
UIApplication.shared.openURL(url)
}
}
Hay dos formas de detectar la interacción del usuario con su vista de anotación. La técnica común es definir una llamada (esa pequeña burbuja emergente estándar que se ve cuando toca un pin en una aplicación de mapas típica) para su MKAnnotationView
. Y crea la vista de anotación para su anotación en el método de viewForAnnotation
estándar:
- (MKAnnotationView *)mapView:(MKMapView *)mapView viewForAnnotation:(id <MKAnnotation>)annotation
{
if ([annotation isKindOfClass:[MKUserLocation class]])
return nil;
MKAnnotationView *annotationView = [[MKPinAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:@"loc"];
annotationView.canShowCallout = YES;
annotationView.rightCalloutAccessoryView = [UIButton buttonWithType:UIButtonTypeDetailDisclosure];
return annotationView;
}
Al hacer esto, obtiene una llamada, pero está agregando un accesorio adecuado, que es, en mi ejemplo anterior, un indicador de divulgación. De esa manera, tocan en su vista de anotación (en mi ejemplo anterior, un pin en el mapa), ven la llamada, y cuando tocan el accesorio correcto de esa llamada (el pequeño indicador de divulgación en este ejemplo), se llama a su calloutAccessoryControlTapped
(en mi ejemplo a continuación, realizar un segue a algún controlador de vista detallada):
- (void)mapView:(MKMapView *)mapView annotationView:(MKAnnotationView *)view calloutAccessoryControlTapped:(UIControl *)control
{
[self performSegueWithIdentifier:@"DetailsIphone" sender:view];
}
Esa es una experiencia de usuario muy típica en la pequeña pantalla del iPhone.
Pero, si no te gusta ese UX y no quieres la llamada estándar, sino que quieres que ocurra algo más, puedes definir tu MKAnnotationView
para que no se muestre una llamada, sino que la interceptes y hagas algo. otra cosa (por ejemplo, en las aplicaciones de mapas de iPad, puede mostrar un popover más sofisticado en lugar de la llamada estándar). Por ejemplo, puede hacer que su MKAnnotationView
no muestre una llamada:
- (MKAnnotationView *)mapView:(MKMapView *)mapView viewForAnnotation:(id <MKAnnotation>)annotation
{
if ([annotation isKindOfClass:[MKUserLocation class]])
return nil;
MKAnnotationView *annotationView = [[MKPinAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:@"loc"];
annotationView.canShowCallout = NO;
return annotationView;
}
Pero luego puede manejar manualmente didSelectAnnotationView
para detectar cuándo un usuario hizo MKAnnotationView
en su MKAnnotationView
, en este ejemplo mostrando una MKAnnotationView
:
- (void)mapView:(MKMapView *)mapView didSelectAnnotationView:(MKAnnotationView *)view
{
[mapView deselectAnnotation:view.annotation animated:YES];
DetailsViewController *controller = [self.storyboard instantiateViewControllerWithIdentifier:@"DetailsPopover"];
controller.annotation = view.annotation;
self.popover = [[UIPopoverController alloc] initWithContentViewController:controller];
self.popover.delegate = self;
[self.popover presentPopoverFromRect:view.frame
inView:view.superview
permittedArrowDirections:UIPopoverArrowDirectionAny
animated:YES];
}
Incluyo algunas instantáneas de pantalla para la interfaz de usuario producidas por el código anterior en mi respuesta aquí .