Anotações e sobreposições no Xamarin.iOS

O aplicativo que vamos criar neste passo a passo é mostrado abaixo:

Um exemplo de aplicativo MapKit

Vamos começar criando um novo Projeto Vazio do iOS e dando-lhe um nome relevante. Começaremos adicionando código ao nosso View Controller para exibir o MapView e, em seguida, criaremos novas classes para nosso MapDelegate e as anotações personalizadas. Siga as etapas abaixo para fazer isso:

ViewController

  1. Adicione os seguintes namespaces ao ViewController:

    using MapKit;
    using CoreLocation;
    using UIKit
    using CoreGraphics
    
  2. Adicione uma variável de MKMapView instância à classe, juntamente com uma MapDelegate instância. Vamos criar o MapDelegate em breve:

    public partial class ViewController : UIViewController
    {
        MKMapView map;
        MapDelegate mapDelegate;
        ...
    
  3. No método do LoadView controlador, adicione um MKMapView e defina-o para a View propriedade do controlador:

    public override void LoadView ()
    {
        map = new MKMapView (UIScreen.MainScreen.Bounds);
        View = map;
    }
    

    Em seguida, adicionaremos código para inicializar o mapa no método 'ViewDidLoad''.

  4. Em ViewDidLoad adicionar código para definir o tipo de mapa, mostre a localização do usuário e permita zoom e movimento panorâmico:

    // change map type, show user location and allow zooming and panning
    map.MapType = MKMapType.Standard;
    map.ShowsUserLocation = true;
    map.ZoomEnabled = true;
    map.ScrollEnabled = true;
    
    
  5. Em seguida, adicione código para centralizar o mapa e defina sua região:

    double lat = 30.2652233534254;
    double lon = -97.73815460962083;
    CLLocationCoordinate2D mapCenter = new CLLocationCoordinate2D (lat, lon);
    MKCoordinateRegion mapRegion = MKCoordinateRegion.FromDistance (mapCenter, 100, 100);
    map.CenterCoordinate = mapCenter;
    map.Region = mapRegion;
    
    
  6. Crie uma nova instância de MapDelegate e atribua-a ao Delegate do MKMapView. Novamente, implementaremos o MapDelegate em breve:

    mapDelegate = new MapDelegate ();
    map.Delegate = mapDelegate;
    
  7. A partir do iOS 8, você deve solicitar autorização do usuário para usar sua localização, então vamos adicionar isso à nossa amostra. Primeiro, defina uma CLLocationManager variável de nível de classe:

    CLLocationManager locationManager = new CLLocationManager();
    
  8. No método, queremos verificar se o dispositivo que executa o aplicativo está usando o ViewDidLoad iOS 8 e, se estiver, solicitaremos autorização quando o aplicativo estiver em uso:

    if (UIDevice.CurrentDevice.CheckSystemVersion(8,0)){
        locationManager.RequestWhenInUseAuthorization ();
    }
    
  9. Finalmente, precisamos editar o arquivo Info.plist para avisar os usuários sobre o motivo de solicitar sua localização. No menu Origem do Info.plist, adicione a seguinte chave:

    NSLocationWhenInUseUsageDescription

    e string:

    Maps Walkthrough Docs Sample.

ConferenceAnnotation.cs – Uma classe para anotações personalizadas

  1. Vamos usar uma classe personalizada para a anotação chamada ConferenceAnnotation. Adicione a seguinte classe ao projeto:

    using System;
    using CoreLocation;
    using MapKit;
    
    namespace MapsWalkthrough
    {
        public class ConferenceAnnotation : MKAnnotation
        {
            string title;
            CLLocationCoordinate2D coord;
    
            public ConferenceAnnotation (string title,
            CLLocationCoordinate2D coord)
            {
                this.title = title;
                this.coord = coord;
            }
    
            public override string Title {
                get {
                    return title;
                }
            }
    
            public override CLLocationCoordinate2D Coordinate {
                get {
                    return coord;
                }
            }
        }
    }
    

ViewController - Adicionando a anotação e a sobreposição

  1. Com o ConferenceAnnotation no lugar, podemos adicioná-lo ao mapa. De volta ao ViewDidLoad método do ViewController, adicione a anotação na coordenada central do mapa:

    map.AddAnnotations (new ConferenceAnnotation ("Evolve Conference", mapCenter));
    
  2. Também queremos ter uma sobreposição do hotel. Adicione o seguinte código para criar o MKPolygon usando as coordenadas para o hotel fornecido, e adicioná-lo ao mapa por chamada AddOverlay:

    // add an overlay of the hotel
    MKPolygon hotelOverlay = MKPolygon.FromCoordinates(
        new CLLocationCoordinate2D[]{
        new CLLocationCoordinate2D(30.2649977168594, -97.73863627705),
        new CLLocationCoordinate2D(30.2648461170005, -97.7381627734755),
        new CLLocationCoordinate2D(30.2648355402574, -97.7381750192576),
        new CLLocationCoordinate2D(30.2647791309417, -97.7379872505988),
        new CLLocationCoordinate2D(30.2654525150319, -97.7377341711021),
        new CLLocationCoordinate2D(30.2654807195004, -97.7377994819399),
        new CLLocationCoordinate2D(30.2655089239607, -97.7377994819399),
        new CLLocationCoordinate2D(30.2656428950368, -97.738346460207),
        new CLLocationCoordinate2D(30.2650364981811, -97.7385709662122),
        new CLLocationCoordinate2D(30.2650470749025, -97.7386199493406)
    });
    
    map.AddOverlay (hotelOverlay);
    

Isso conclui o código no ViewDidLoad. Agora precisamos implementar nossa MapDelegate classe para lidar com a criação das exibições de anotação e sobreposição, respectivamente.

MapDelegar

  1. Crie uma classe chamada MapDelegate que herda de e inclua uma annotationId variável para usar como um identificador de MKMapViewDelegate reutilização para a anotação:

    class MapDelegate : MKMapViewDelegate
    {
        static string annotationId = "ConferenceAnnotation";
        ...
    }
    

    Temos apenas uma anotação aqui, então o código de reutilização não é estritamente necessário, mas é uma boa prática incluí-lo.

  2. Implemente o GetViewForAnnotation método para retornar um modo de exibição para o uso da ConferenceAnnotation imagem conference.png incluída com este passo a passo:

    public override MKAnnotationView GetViewForAnnotation (MKMapView mapView, NSObject annotation)
    {
        MKAnnotationView annotationView = null;
    
        if (annotation is MKUserLocation)
            return null;
    
        if (annotation is ConferenceAnnotation) {
    
            // show conference annotation
            annotationView = mapView.DequeueReusableAnnotation (annotationId);
    
            if (annotationView == null)
                annotationView = new MKAnnotationView (annotation, annotationId);
    
            annotationView.Image = UIImage.FromFile ("images/conference.png");
            annotationView.CanShowCallout = true;
        }
    
        return annotationView;
    }
    
  3. Quando o usuário toca na anotação, queremos exibir uma imagem mostrando a cidade de Austin. Adicione as seguintes variáveis ao MapDelegate para a imagem e ao modo de exibição para exibi-lo:

    UIImageView venueView;
    UIImage venueImage;
    
  4. Em seguida, para mostrar a imagem quando a anotação for tocada, implemente o DidSelectAnnotation método da seguinte maneira:

    public override void DidSelectAnnotationView (MKMapView mapView, MKAnnotationView view)
    {
        // show an image view when the conference annotation view is selected
        if (view.Annotation is ConferenceAnnotation) {
    
            venueView = new UIImageView ();
            venueView.ContentMode = UIViewContentMode.ScaleAspectFit;
            venueImage = UIImage.FromFile ("image/venue.png");
            venueView.Image = venueImage;
            view.AddSubview (venueView);
    
            UIView.Animate (0.4, () => {
            venueView.Frame = new CGRect (-75, -75, 200, 200); });
        }
    }
    
  5. Para ocultar a imagem quando o usuário desmarcar a anotação tocando em qualquer outro lugar no mapa, implemente o DidDeselectAnnotationView método da seguinte maneira:

    public override void DidDeselectAnnotationView (MKMapView mapView, MKAnnotationView view)
    {
        // remove the image view when the conference annotation is deselected
        if (view.Annotation is ConferenceAnnotation) {
    
            venueView.RemoveFromSuperview ();
            venueView.Dispose ();
            venueView = null;
        }
    }
    

    Agora temos o código para a anotação em vigor. Tudo o MapDelegate que resta é adicionar código ao para criar a exibição para a sobreposição do hotel.

  6. Adicione a seguinte implementação do GetViewForOverlayMapDelegate:

    public override MKOverlayView GetViewForOverlay (MKMapView mapView, NSObject overlay)
    {
        // return a view for the polygon
        MKPolygon polygon = overlay as MKPolygon;
        MKPolygonView polygonView = new MKPolygonView (polygon);
        polygonView.FillColor = UIColor.Blue;
        polygonView.StrokeColor = UIColor.Red;
        return polygonView;
    }
    

Execute o aplicativo. Agora temos um mapa interativo com uma anotação personalizada e uma sobreposição! Toque na anotação e a imagem de Austin é exibida, como mostrado abaixo:

Toque na anotação e a imagem de Austin é exibida

Resumo

Neste artigo, analisamos como adicionar uma anotação a um mapa, bem como adicionar uma sobreposição para um polígono especificado. Também demonstramos como adicionar suporte de toque à anotação para animar uma imagem sobre um mapa.