Freigeben über


Neue Features in MapKit unter iOS 11

iOS 11 fügt mapKit die folgenden neuen Features hinzu:

Karte mit gruppierten Markierungen und Kompasstaste

Automatisches Gruppieren von Markierungen beim Zoomen

Das Beispiel zeigt, wie das neue iOS 11-Anmerkungsclustering-Feature implementiert wird.

1. Erstellen einer MKPointAnnotation Unterklasse

Die Punktanmerkungsklasse stellt jede Markierung auf der Karte dar. Sie können einzeln mithilfe MapView.AddAnnotation() oder aus einem Array hinzugefügt MapView.AddAnnotations()werden.

Punktanmerkungsklassen verfügen nicht über eine visuelle Darstellung, sie sind nur erforderlich, um die mit der Markierung verknüpften Daten darzustellen (vor allem die Eigenschaft, die Coordinate breiten- und längengrad auf der Karte ist) und alle benutzerdefinierten Eigenschaften:

public class Bike : MKPointAnnotation
{
  public BikeType Type { get; set; } = BikeType.Tricycle;
  public Bike(){}
  public Bike(NSNumber lat, NSNumber lgn, NSNumber type)
  {
    Coordinate = new CLLocationCoordinate2D(lat.NFloatValue, lgn.NFloatValue);
    switch(type.NUIntValue) {
      case 0:
        Type = BikeType.Unicycle;
        break;
      case 1:
        Type = BikeType.Tricycle;
        break;
    }
  }
}

2. Erstellen einer MKMarkerAnnotationView Unterklasse für einzelne Markierungen

Die Markierungsanmerkungsansicht ist die visuelle Darstellung jeder Anmerkung und wird mithilfe von Eigenschaften wie:

  • MarkerTintColor – Die Farbe für die Markierung.
  • GlyphText – Text, der in der Markierung angezeigt wird.
  • GlyphImage – Legt das Bild fest, das in der Markierung angezeigt wird.
  • DisplayPriority – Bestimmt die Z-Reihenfolge (Stapelverhalten), wenn die Karte mit Markierungen überfüllt ist. Verwenden Sie einen von Required, , DefaultHighoder DefaultLow.

Um die automatische Clustering zu unterstützen, müssen Sie auch Folgendes festlegen:

  • ClusteringIdentifier – Dies steuert, welche Markierungen gruppiert werden. Sie können denselben Bezeichner für alle Ihre Markierungen verwenden oder unterschiedliche Bezeichner verwenden, um die Art und Weise zu steuern, wie sie gruppiert werden.
[Register("BikeView")]
public class BikeView : MKMarkerAnnotationView
{
  public static UIColor UnicycleColor = UIColor.FromRGB(254, 122, 36);
  public static UIColor TricycleColor = UIColor.FromRGB(153, 180, 44);
  public override IMKAnnotation Annotation
  {
    get {
      return base.Annotation;
    }
    set {
      base.Annotation = value;

      var bike = value as Bike;
      if (bike != null){
        ClusteringIdentifier = "bike";
        switch(bike.Type){
          case BikeType.Unicycle:
            MarkerTintColor = UnicycleColor;
            GlyphImage = UIImage.FromBundle("Unicycle");
            DisplayPriority = MKFeatureDisplayPriority.DefaultLow;
            break;
          case BikeType.Tricycle:
            MarkerTintColor = TricycleColor;
            GlyphImage = UIImage.FromBundle("Tricycle");
            DisplayPriority = MKFeatureDisplayPriority.DefaultHigh;
            break;
        }
      }
    }
  }

3. Erstellen sie eine MKAnnotationView , die Cluster von Markern darstellt

Während die Anmerkungsansicht, die einen Cluster von Markierungen darstellt, ein einfaches Bild sein könnte , erwarten Die Benutzer, dass die App visuelle Hinweise dazu liefert, wie viele Markierungen gruppiert wurden.

Im Beispiel wird CoreGraphics verwendet, um die Anzahl der Markierungen im Cluster sowie eine Kreisdiagrammdarstellung des Proportionen jedes Markertyps zu rendern.

Sie sollten auch Folgendes festlegen:

  • DisplayPriority – Bestimmt die Z-Reihenfolge (Stapelverhalten), wenn die Karte mit Markierungen überfüllt ist. Verwenden Sie einen von Required, , DefaultHighoder DefaultLow.
  • CollisionModeCircle oder Rectangle.
[Register("ClusterView")]
public class ClusterView : MKAnnotationView
{
  public static UIColor ClusterColor = UIColor.FromRGB(202, 150, 38);
  public override IMKAnnotation Annotation
  {
    get {
      return base.Annotation;
    }
    set {
      base.Annotation = value;
      var cluster = MKAnnotationWrapperExtensions.UnwrapClusterAnnotation(value);
      if (cluster != null)
      {
        var renderer = new UIGraphicsImageRenderer(new CGSize(40, 40));
        var count = cluster.MemberAnnotations.Length;
        var unicycleCount = CountBikeType(cluster.MemberAnnotations, BikeType.Unicycle);

        Image = renderer.CreateImage((context) => {
          // Fill full circle with tricycle color
          BikeView.TricycleColor.SetFill();
          UIBezierPath.FromOval(new CGRect(0, 0, 40, 40)).Fill();
          // Fill pie with unicycle color
          BikeView.UnicycleColor.SetFill();
          var piePath = new UIBezierPath();
          piePath.AddArc(new CGPoint(20,20), 20, 0, (nfloat)(Math.PI * 2.0 * unicycleCount / count), true);
          piePath.AddLineTo(new CGPoint(20, 20));
          piePath.ClosePath();
          piePath.Fill();
          // Fill inner circle with white color
          UIColor.White.SetFill();
          UIBezierPath.FromOval(new CGRect(8, 8, 24, 24)).Fill();
          // Finally draw count text vertically and horizontally centered
          var attributes = new UIStringAttributes() {
            ForegroundColor = UIColor.Black,
            Font = UIFont.BoldSystemFontOfSize(20)
          };
          var text = new NSString($"{count}");
          var size = text.GetSizeUsingAttributes(attributes);
          var rect = new CGRect(20 - size.Width / 2, 20 - size.Height / 2, size.Width, size.Height);
          text.DrawString(rect, attributes);
        });
      }
    }
  }
  public ClusterView(){}
  public ClusterView(MKAnnotation annotation, string reuseIdentifier) : base(annotation, reuseIdentifier)
  {
    DisplayPriority = MKFeatureDisplayPriority.DefaultHigh;
    CollisionMode = MKAnnotationViewCollisionMode.Circle;
    // Offset center point to animate better with marker annotations
    CenterOffset = new CoreGraphics.CGPoint(0, -10);
  }
  private nuint CountBikeType(IMKAnnotation[] members, BikeType type) {
    nuint count = 0;
    foreach(Bike member in members){
      if (member.Type == type) ++count;
    }
    return count;
  }
}

4. Registrieren der Ansichtsklassen

Wenn das Kartenansichtssteuerelement erstellt und einer Ansicht hinzugefügt wird, registrieren Sie die Anmerkungsansichtstypen, um das automatische Clusteringverhalten zu aktivieren, wenn die Karte vergrößert und verkleinert wird:

MapView.Register(typeof(BikeView), MKMapViewDefault.AnnotationViewReuseIdentifier);
MapView.Register(typeof(ClusterView), MKMapViewDefault.ClusterAnnotationViewReuseIdentifier);

5. Rendern Sie die Karte!

Wenn die Karte gerendert wird, werden Anmerkungenmarkierungen gruppiert oder gerendert, je nach Zoomfaktor. Wenn sich der Zoomfaktor ändert, werden Markierungen in und außerhalb von Clustern animiert.

Simulator mit gruppierten Markierungen auf der Karte

Weitere Informationen zum Anzeigen von Daten mit MapKit finden Sie im Abschnitt Karten.

Kompasstaste

iOS 11 bietet die Möglichkeit, den Kompass aus der Karte herauszufüllen und an anderer Stelle in der Ansicht zu rendern.

Erstellen Sie eine Schaltfläche, die wie ein Kompass aussieht (einschließlich Liveanimation, wenn die Kartenausrichtung geändert wird), und rendert sie auf einem anderen Steuerelement.

Kompasstaste in der Navigationsleiste

Der folgende Code erstellt eine Kompasstaste und rendert sie auf der Navigationsleiste:

var compass = MKCompassButton.FromMapView(MapView);
compass.CompassVisibility = MKFeatureVisibility.Visible;
NavigationItem.RightBarButtonItem = new UIBarButtonItem(compass);
MapView.ShowsCompass = false; // so we don't have two compasses!

Die ShowsCompass Eigenschaft kann verwendet werden, um die Sichtbarkeit des Standardkompasss innerhalb der Kartenansicht zu steuern.

Skalierungsansicht

Fügen Sie die Skalierung an anderer Stelle in der Ansicht mithilfe der MKScaleView.FromMapView() Methode hinzu, um eine Instanz der Skalierungsansicht abzurufen, die an anderer Stelle in der Ansichtshierarchie hinzugefügt werden soll.

Überlagerte Skalierungsansicht auf einer Karte

var scale = MKScaleView.FromMapView(MapView);
scale.LegendAlignment = MKScaleViewAlignment.Trailing;
scale.TranslatesAutoresizingMaskIntoConstraints = false;
View.AddSubview(scale); // constraints omitted for simplicity
MapView.ShowsScale = false; // so we don't have two scale displays!

Die ShowsScale Eigenschaft kann verwendet werden, um die Sichtbarkeit des Standardkompasss innerhalb der Kartenansicht zu steuern.

Schaltfläche "Benutzerverfolgung"

Die Schaltfläche "Benutzerverfolgung" zentrieren die Karte auf der aktuellen Position des Benutzers. Verwenden Sie die MKUserTrackingButton.FromMapView() Methode, um eine Instanz der Schaltfläche abzurufen, Formatierungsänderungen anzuwenden und an anderer Stelle in der Ansichtshierarchie hinzuzufügen.

Schaltfläche

var button = MKUserTrackingButton.FromMapView(MapView);
button.Layer.BackgroundColor = UIColor.FromRGBA(255,255,255,80).CGColor;
button.Layer.BorderColor = UIColor.White.CGColor;
button.Layer.BorderWidth = 1;
button.Layer.CornerRadius = 5;
button.TranslatesAutoresizingMaskIntoConstraints = false;
View.AddSubview(button); // constraints omitted for simplicity