Ескертпе
Бұл бетке кіру үшін қатынас шегін айқындау қажет. Жүйеге кіруді немесе каталогтарды өзгертуді байқап көруге болады.
Бұл бетке кіру үшін қатынас шегін айқындау қажет. Каталогтарды өзгертуді байқап көруге болады.
IOS 11 добавляет следующие новые функции в MapKit:
- Кластеризация заметок
- Кнопка компаса
- Представление масштабирования
- Кнопка отслеживания пользователей

Автоматическое группирование маркеров при масштабировании
В примере показано, как реализовать новую функцию заметки iOS 11 кластеризация.
1. Создание подкласса MKPointAnnotation
Класс заметки точки представляет каждый маркер на карте. Их можно добавлять по отдельности с помощью MapView.AddAnnotation()MapView.AddAnnotations()или из массива.
Классы заметок точек не имеют визуального представления, они необходимы только для представления данных, связанных с маркером (самое главное, свойство, Coordinate которое является его широтой и долготой на карте), и любыми пользовательскими свойствами:
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. Создание подкласса MKMarkerAnnotationView для отдельных маркеров
Представление заметки маркера — это визуальное представление каждой заметки, и стиль выполняется с помощью таких свойств, как:
- MarkerTintColor — цвет маркера.
- GlyphText — текст, отображаемый в маркере.
- GlyphImage — задает изображение, отображаемое в маркере.
- DisplayPriority — определяет z-порядок (поведение стека) при переполнении карты маркерами. Используйте один из
Required,DefaultHighилиDefaultLow.
Чтобы поддерживать автоматическую кластеризация, необходимо также задать следующее:
- ClusteringIdentifier — это элементы управления, которые маркеры группируются вместе. Вы можете использовать один и тот же идентификатор для всех маркеров или использовать разные идентификаторы для управления способом их группировки.
[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. Создание MKAnnotationView кластера маркеров для представления кластеров маркеров
Хотя представление заметки, представляющее кластер маркеров, может быть простым изображением, пользователи ожидают, что приложение будет предоставлять визуальные подсказки о том, сколько маркеров сгруппировано вместе.
В примере используются CoreGraphics для отрисовки количества маркеров в кластере, а также представление кольцевого графа пропорции каждого типа маркера.
Также следует задать следующее:
- DisplayPriority — определяет z-порядок (поведение стека) при переполнении карты маркерами. Используйте один из
Required,DefaultHighилиDefaultLow. - CollisionMode —
Circleили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. Регистрация классов представления
Когда элемент управления представлением карты создается и добавляется в представление, зарегистрируйте типы представлений заметок, чтобы включить автоматическое кластеризация поведение по мере увеличения и увеличения карты:
MapView.Register(typeof(BikeView), MKMapViewDefault.AnnotationViewReuseIdentifier);
MapView.Register(typeof(ClusterView), MKMapViewDefault.ClusterAnnotationViewReuseIdentifier);
5. Отрисовка карты!
При отрисовки карты маркеры заметок будут кластеризованы или отрисованы в зависимости от уровня масштабирования. По мере изменения уровня масштабирования маркеры анимировать и выходить из кластеров.

Дополнительные сведения о отображении данных с помощью MapKit см. в разделе Карты.
Кнопка компаса
iOS 11 добавляет возможность всплывать компас из карты и отображать его в другом месте в представлении.
Создайте кнопку, которая выглядит как компас (включая динамическую анимацию при изменении ориентации карты) и отрисовывает ее на другом элементе управления.

Приведенный ниже код создает кнопку компаса и отрисовывает ее на панели навигации:
var compass = MKCompassButton.FromMapView(MapView);
compass.CompassVisibility = MKFeatureVisibility.Visible;
NavigationItem.RightBarButtonItem = new UIBarButtonItem(compass);
MapView.ShowsCompass = false; // so we don't have two compasses!
Свойство ShowsCompass можно использовать для управления видимостью компаса по умолчанию в представлении карты.
Представление масштабирования
Добавьте масштаб в другое место в представлении, используя MKScaleView.FromMapView() метод, чтобы получить экземпляр представления масштабирования для добавления в другое место в иерархии представлений.

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!
Свойство ShowsScale можно использовать для управления видимостью компаса по умолчанию в представлении карты.
Кнопка отслеживания пользователей
Кнопка отслеживания пользователей центрируется на карте в текущем расположении пользователя. MKUserTrackingButton.FromMapView() Используйте метод для получения экземпляра кнопки, применения изменений форматирования и добавления в другой части иерархии представлений.

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