Neue Features in MapKit unter iOS 11
iOS 11 fügt MapKit die folgenden neuen Features hinzu:
Automatisches Gruppieren von Markern beim Zoomen
Das MapKit-Beispiel "Tandm" zeigt, wie Sie das neue Feature für das Clustering von iOS 11-Anmerkungen implementieren.
1. Erstellen einer MKPointAnnotation
Unterklasse
Die Punktanmerkungsklasse stellt jeden Marker auf der Karte dar. Sie können einzeln mithilfe MapView.AddAnnotation()
von oder aus einem Array mit MapView.AddAnnotations()
hinzugefügt werden.
Punktanmerkungsklassen verfügen nicht über eine visuelle Darstellung, sie müssen nur die Daten darstellen, die dem Marker zugeordnet sind (vor allem die Eigenschaft, die Coordinate
ihren Breiten- und Längengrad auf der Karte darstellt) 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 Marker
Die Markeranmerkungsansicht ist die visuelle Darstellung jeder Anmerkung und wird mithilfe von Eigenschaften wie folgenden formatiert:
- MarkerTintColor : Die Farbe für den Marker.
- GlyphText – Text, der im Marker angezeigt wird.
- GlyphImage : Legt das Bild fest, das im Marker angezeigt wird.
- DisplayPriority : Bestimmt die Z-Reihenfolge (Stapelverhalten), wenn die Karte mit Markern überlastet ist. Verwenden Sie eine von
Required
,DefaultHigh
oderDefaultLow
.
Um das automatische Clustering zu unterstützen, müssen Sie auch Folgendes festlegen:
- ClusteringIdentifier : Hiermit wird gesteuert, welche Marker gruppiert werden. Sie können denselben Bezeichner für alle Ihre Marker 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 eines MKAnnotationView
zum Darstellen von Markerclustern
Während die Anmerkungsansicht, die einen Markercluster darstellt, ein einfaches Bild sein kann , erwarten Benutzer, dass die App visuelle Hinweise dazu liefert, wie viele Marker gruppiert wurden.
Der Beispielcode verwendet CoreGraphics, um die Anzahl der Marker im Cluster sowie eine Kreisdiagrammdarstellung des Anteils jedes Markertyps zu rendern.
Sie sollten auch Folgendes festlegen:
- DisplayPriority : Bestimmt die Z-Reihenfolge (Stapelverhalten), wenn die Karte mit Markern überlastet ist. Verwenden Sie eine von
Required
,DefaultHigh
oderDefaultLow
. - CollisionMode –
Circle
oderRectangle
.
[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 Kartenansicht-Steuerelement erstellt und einer Ansicht hinzugefügt wird, registrieren Sie die Anmerkungsansichtstypen, um das automatische Clusteringverhalten zu aktivieren, wenn die Karte verkleinert 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 Anmerkungsmarker gruppiert oder je nach Zoomfaktor gerendert. Wenn sich der Zoomfaktor ändert, animieren Marker in und aus Clustern.
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 zu klappen und ihn an anderer Stelle in der Ansicht zu rendern. Ein Beispiel finden Sie in der Tandm-Beispiel-App .
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.
Der folgende Code erstellt eine Kompassschaltfläche 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 Standardkompasses in der Kartenansicht zu steuern.
Skalierungsansicht
Fügen Sie die Skalierung an einer anderen Stelle in der Ansicht hinzu, indem Sie die MKScaleView.FromMapView()
-Methode verwenden, um eine instance der Skalierungsansicht abzurufen, die an einer anderen Stelle in der Ansichtshierarchie hinzugefügt werden soll.
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 Standardkompasses in der Kartenansicht zu steuern.
Schaltfläche "Benutzernachverfolgung"
Die Schaltfläche "Benutzernachverfolgung" zentriert die Karte auf den aktuellen Standort des Benutzers. Verwenden Sie die MKUserTrackingButton.FromMapView()
-Methode, um eine instance der Schaltfläche abzurufen, Formatierungsänderungen anzuwenden und an einer anderen Stelle in der Ansichtshierarchie hinzuzufügen.
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