Подтвердить что ты не робот

Событие переключения MKMapView MKPointAnnotation

У меня есть список аннотаций (MKPointAnnotation). У меня есть UIViewController, который предназначен для всего представления, MKMapView, реализующего Controller, который, как мне показалось, полезен для обнаружения взаимодействия пользователей с картой, моего собственного контроллера MKPointAnnotation (подкласс), который рассказывает, как показать аннотацию.

Однако я поражен обнаружением пользователем события нажатия.

Googling сказал мне, что я должен что-то сделать, реализовав следующую функцию.

- (void)mapView:(MKMapView *)mapView annotationView:(MKAnnotationView *)view calloutAccessoryControlTapped:(UIControl *)control

а также что я должен реализовать это в некотором классе, который реализует MapViewDelegate (Protocol).

Но я все смущен и не могу двигаться вперед. Может ли кто-нибудь сказать мне, что делать?

Извините за всю суету!

4b9b3361

Ответ 1

Существует два способа обнаружения взаимодействия пользователя с вашим аннотационным представлением. Общей методикой является определение выноски (этот стандартный маленький пузырь, который вы видите, когда вы нажимаете на булавку в типичном приложении для карт) для вашего MKAnnotationView. И вы создаете аннотацию для своей аннотации в стандартном методе viewForAnnotation:

- (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;
}

При этом вы получаете выноску, но вы добавляете правильный аксессуар, который, в моем примере выше, является индикатором раскрытия. Таким образом, они нажимают на ваш аннотационный вид (в моем примере выше, вырез на карте), они видят выноску, и когда они нажимают на этот аксессуар правой руки (маленький индикатор раскрытия информации в этом примере), ваш calloutAccessoryControlTapped (в моем примере ниже, выполняя segue для некоторого контроллера подробного представления):

- (void)mapView:(MKMapView *)mapView annotationView:(MKAnnotationView *)view calloutAccessoryControlTapped:(UIControl *)control
{
    [self performSegueWithIdentifier:@"DetailsIphone" sender:view];
}

Это очень типичный пользовательский интерфейс на маленьком экране iPhone.

Но если вам не нравится этот UX, и вам не нужна стандартная выноска, но вы хотите, чтобы что-то еще произошло, вы можете определить свой MKAnnotationView, чтобы выноска не была показана, но вместо этого вы перехватите его и сделайте что-нибудь еще (например, в приложениях для iPad-карт, вы можете показать более сложный popover, а не стандартную выноску). Например, вы можете иметь MKAnnotationView не показывать выноску:

- (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;
}

Но вы можете вручную обработать didSelectAnnotationView, чтобы определить, когда пользователь нажал на ваш MKAnnotationView, в этом примере показано popover:

- (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];
}

Я включаю некоторые снимки экрана для пользовательского интерфейса, предоставленные приведенным выше кодом, в моем ответе здесь.

Ответ 2

Добавить кнопку в этом методе

-(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];

} 

Ответ 3

Пример Robs для 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)
    }
}