IOS 11의 MapKit의 새로운 기능New Features in MapKit on iOS 11

iOS 11은 다음과 같은 새 기능을 MapKit에 추가 합니다.iOS 11 adds the following new features to MapKit:

클러스터형 표식 및 나침반 단추를 표시 하는 맵

확대/축소 하는 동안 자동으로 표식 그룹화Automatically grouping markers while zooming

샘플 Mapkit 샘플 "Tandm" 에서는 새 iOS 11 주석 클러스터링 기능을 구현 하는 방법을 보여 줍니다.The sample MapKit Sample "Tandm" shows how to implement the new iOS 11 annotation clustering feature.

1. MKPointAnnotation 하위 클래스 만들기1. Create an MKPointAnnotation subclass

Point annotation 클래스는 맵의 각 표식을 나타냅니다.The point annotation class represents each marker on the map. 을 사용 하 여 또는 배열에서 개별적으로 추가할 수 있습니다 MapView.AddAnnotation() MapView.AddAnnotations() .They can be added individually using MapView.AddAnnotation() or from an array using MapView.AddAnnotations().

Point annotation 클래스에는 시각적 표현이 없습니다. 표식 (가장 중요 한 Coordinate 것은 지도의 위도 및 경도 인 속성) 및 사용자 지정 속성을 나타내는 데만 필요 합니다.Point annotation classes do not have a visual representation, they are only required to represent the data associated with the marker (most importantly, the Coordinate property which is its latitude and longitude on the map), and any custom properties:

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 단일 표식에 대 한 하위 클래스 만들기2. Create an MKMarkerAnnotationView subclass for single markers

표식 주석 보기는 각 주석의 시각적 표시 이며 다음과 같은 속성을 사용 하 여 스타일이 지정 됩니다.The marker annotation view is the visual representation of each annotation, and is styled using properties such as:

  • MarkerTintColor – 표식의 색입니다.MarkerTintColor – The color for the marker.
  • GlyphText – 표식에 표시 되는 텍스트입니다.GlyphText – Text displayed in the marker.
  • GlyphImage – 표식에 표시 되는 이미지를 설정 합니다.GlyphImage – Sets the image that is displayed in the marker.
  • DisplayPriority – map이 표식으로 복잡 한 경우 z 순서 (스택 동작)를 결정 합니다.DisplayPriority – Determines z-order (stacking behavior) when the map is crowded with markers. Required, 또는 중 하나를 사용 DefaultHigh DefaultLow 합니다.Use one of Required, DefaultHigh, or DefaultLow.

자동 클러스터링을 지원 하려면 다음도 설정 해야 합니다.To support automatic clustering, you must also set:

  • Clusteringidentifier – 함께 클러스터링 된 마커를 제어 합니다.ClusteringIdentifier – This controls which markers get clustered together. 모든 표식에 동일한 식별자를 사용 하거나 서로 다른 식별자를 사용 하 여 그룹화 하는 방법을 제어할 수 있습니다.You can use the same identifier for all your markers, or use different identifiers to control the way they are grouped together.
[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 표식의 클러스터를 나타내는를 만듭니다.3. Create an MKAnnotationView to represent clusters of markers

표식의 클러스터를 나타내는 주석 보기는 간단한 이미지인 반면, 사용자는 앱이 그룹화 된 표식의 수에 대 한 시각적 표시를 제공 하는 것으로 간주 합니다.While the annotation view that represents a cluster of markers could be a simple image, users expect the app to provide visual cues about how many markers have been grouped together.

샘플 코드 에서는 CoreGraphics를 사용 하 여 클러스터의 마커 수와 각 표식 유형 비율의 원 그래프 표현을 렌더링 합니다.The sample code uses CoreGraphics to render the number of markers in the cluster, as well as a circle-graph representation of the proportion of each marker type.

또한 다음과 같이 설정 해야 합니다.You should also set:

  • DisplayPriority – map이 표식으로 복잡 한 경우 z 순서 (스택 동작)를 결정 합니다.DisplayPriority – Determines z-order (stacking behavior) when the map is crowded with markers. Required, 또는 중 하나를 사용 DefaultHigh DefaultLow 합니다.Use one of Required, DefaultHigh, or DefaultLow.
  • CollisionModeCircle 또는 Rectangle 입니다.CollisionModeCircle or 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. 뷰 클래스 등록4. Register the view classes

지도 보기 컨트롤이 만들어지고 뷰에 추가 될 때 맵이 확대 및 축소 될 때 자동 클러스터링 동작을 사용 하도록 설정 하려면 주석 보기 형식을 등록 합니다.When the map view control is being created and added to a view, register the annotation view types to enable the automatic clustering behavior as the map is zoomed in and out:

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

5. 지도를 렌더링 합니다.5. Render the map!

지도를 렌더링 하면 확대/축소 수준에 따라 주석 표식이 클러스터링 되거나 렌더링 됩니다.When the map is rendered, annotation markers will be clustered or rendered depending on the zoom level. 확대/축소 수준이 변경 됨에 따라 마커는 클러스터에 애니메이션을 적용 합니다.As the zoom level changes, markers animate in and out of clusters.

지도에서 클러스터형 표식을 보여 주는 시뮬레이터

MapKit를 사용 하 여 데이터를 표시 하는 방법에 대 한 자세한 내용은 맵 섹션 을 참조 하세요.Refer to the Maps section for more information on displaying data with MapKit.

나침반 단추Compass Button

iOS 11은 지도에서 나침반을 팝 하 고 뷰의 다른 위치에 렌더링 하는 기능을 추가 합니다.iOS 11 adds the ability to pop the compass out of the map and render it elsewhere in the view. 예는 Tandm 샘플 앱 을 참조 하세요.See the Tandm sample app for an example.

나침반 (지도 방향이 변경 될 때 라이브 애니메이션 포함) 처럼 보이는 단추를 만들고 다른 컨트롤에 렌더링 합니다.Create a button that looks like a compass (including live animation when the map orientation is changed), and renders it on another control.

탐색 모음의 나침반 단추

아래 코드는 나침반 단추를 만들고 탐색 모음에 렌더링 합니다.The code below creates a compass button and renders it on the navigation bar:

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속성은 지도 보기 내에서 기본 나침반의 표시 여부를 제어 하는 데 사용할 수 있습니다.The ShowsCompass property can be used to control visibility of the default compass inside the map view.

눈금 보기Scale View

MKScaleView.FromMapView() 계층의 다른 곳에 추가 하기 위해 메서드를 사용 하 여 뷰의 다른 위치에 눈금을 추가 합니다.Add the scale elsewhere in the view using the MKScaleView.FromMapView() method to get an instance of the scale view to add elsewhere in the view hierarchy.

지도에 중첩 된 눈금 보기

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속성은 지도 보기 내에서 기본 나침반의 표시 여부를 제어 하는 데 사용할 수 있습니다.The ShowsScale property can be used to control visibility of the default compass inside the map view.

사용자 추적 단추User Tracking Button

사용자 추적 단추는 사용자의 현재 위치에 대 한 지도의 가운데 맞춤을 설정 합니다.The user tracking button centers the map on the user's current location. 메서드를 사용 MKUserTrackingButton.FromMapView() 하 여 단추의 인스턴스를 가져오고, 형식 변경을 적용 하 고, 뷰 계층의 다른 위치에 추가 합니다.Use the MKUserTrackingButton.FromMapView() method to get an instance of the button, apply formatting changes, and add elsewhere in the view hierarchy.

맵에 겹쳐진 사용자 위치 단추

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