如何实现在Objective-C MKClusterAnnotations?

问题描述 投票:3回答:2

我努力使集群的意见对于那些真正接近对方对我的苹果地图的注解。我知道苹果已经本土集群视图工具包出来与iOS 11,但所有的教程我能在网上找到的都写在斯威夫特。我希望有人能教我或我推荐,我能读,找出如何实现在Objective-C集群注释任何教程。

我的想法是创建一个安装ClusterView类,它继承了MKAnnotationView类,然后在MapView的控制器创建了ClusterView的实例。

我已阅读来自苹果,它只是提供了我可能需要调用函数的文档,但它并没有解释如何使用他们,这是链接到苹果文档:https://developer.apple.com/documentation/mapkit/mkclusterannotation?language=objc

任何帮助,将不胜感激!

ios objective-c mkmapview mkannotation
2个回答
2
投票

以下是基本步骤:

  1. 定义你的注解视图,指定clusteringIdentifiercollisionMode// CustomAnnotationView.h @import MapKit; @interface CustomAnnotationView : MKMarkerAnnotationView @end // CustomAnnotationView.m #import "CustomAnnotationView.h" static NSString *identifier = @"com.domain.clusteringIdentifier"; @implementation CustomAnnotationView - (instancetype)initWithAnnotation:(id<MKAnnotation>)annotation reuseIdentifier:(NSString *)reuseIdentifier { if ((self = [super initWithAnnotation:annotation reuseIdentifier:reuseIdentifier])) { self.clusteringIdentifier = identifier; self.collisionMode = MKAnnotationViewCollisionModeCircle; } return self; } - (void)setAnnotation:(id<MKAnnotation>)annotation { [super setAnnotation:annotation]; self.clusteringIdentifier = identifier; } @end
  2. 或者,如果你愿意,你可以定义自己的集群标注视图,指定displayPrioritycollisionMode。这其中还更新图像群集说明有多少注解集群: // ClusterAnnotationView.h @import MapKit; @interface ClusterAnnotationView : MKAnnotationView @end // ClusterAnnotationView.m #import "ClusterAnnotationView.h" @implementation ClusterAnnotationView - (instancetype)initWithAnnotation:(id<MKAnnotation>)annotation reuseIdentifier:(NSString *)reuseIdentifier { if ((self = [super initWithAnnotation:annotation reuseIdentifier:reuseIdentifier])) { self.displayPriority = MKFeatureDisplayPriorityDefaultHigh; self.collisionMode = MKAnnotationViewCollisionModeCircle; } return self; } - (void)setAnnotation:(id<MKAnnotation>)annotation { super.annotation = annotation; [self updateImage:annotation]; } - (void)updateImage:(MKClusterAnnotation *)cluster { if (!cluster) { self.image = nil; return; } CGRect rect = CGRectMake(0, 0, 40, 40); UIGraphicsImageRenderer *renderer = [[UIGraphicsImageRenderer alloc] initWithSize:rect.size]; self.image = [renderer imageWithActions:^(UIGraphicsImageRendererContext * _Nonnull rendererContext) { // circle [[UIColor blueColor] setFill]; [[UIColor whiteColor] setStroke]; UIBezierPath *path = [UIBezierPath bezierPathWithOvalInRect:rect]; path.lineWidth = 0.5; [path fill]; [path stroke]; // count NSString *text = [NSString stringWithFormat:@"%ld", (long) cluster.memberAnnotations.count]; NSDictionary<NSAttributedStringKey, id> *attributes = @{ NSFontAttributeName: [UIFont preferredFontForTextStyle: UIFontTextStyleBody], NSForegroundColorAttributeName: [UIColor whiteColor] }; CGSize size = [text sizeWithAttributes:attributes]; CGRect textRect = CGRectMake(rect.origin.x + (rect.size.width - size.width) / 2, rect.origin.y + (rect.size.height - size.height) / 2, size.width, size.height); [text drawInRect:textRect withAttributes:attributes]; }]; } @end 您不必创建自己的子类集群,如果你不想。但是,这只是说明了如何可以完全控制集群的出现,你应该选择这样做。
  3. 那么你的视图控制器只需要注册适当的类,你就大功告成了(没有地图视图代表需要): [self.mapView registerClass:[CustomAnnotationView class] forAnnotationViewWithReuseIdentifier:MKMapViewDefaultAnnotationViewReuseIdentifier]; 如果你想使用自定义聚类图,你可以注册,太: [self.mapView registerClass:[ClusterAnnotationView class] forAnnotationViewWithReuseIdentifier:MKMapViewDefaultClusterAnnotationViewReuseIdentifier]; 例如: // ViewController.m #import “ViewController.h" @import MapKit; #import "CustomAnnotationView.h" #import "ClusterAnnotationView.h" @interface ViewController () @property (weak, nonatomic) IBOutlet MKMapView *mapView; @end @implementation ViewController - (void)viewDidLoad { [super viewDidLoad]; [self configureMapView]; } - (void)configureMapView { self.mapView.userTrackingMode = MKUserTrackingModeFollow; [self.mapView registerClass:[CustomAnnotationView class] forAnnotationViewWithReuseIdentifier:MKMapViewDefaultAnnotationViewReuseIdentifier]; [self.mapView registerClass:[ClusterAnnotationView class] forAnnotationViewWithReuseIdentifier:MKMapViewDefaultClusterAnnotationViewReuseIdentifier]; } // I’m going to search for restaurants and add annotations for those, // but do whatever you want - (void)performSearch { MKLocalSearchRequest *request = [[MKLocalSearchRequest alloc] init]; request.naturalLanguageQuery = @"restaurant"; request.region = self.mapView.region; MKLocalSearch *search = [[MKLocalSearch alloc] initWithRequest:request]; [search startWithCompletionHandler:^(MKLocalSearchResponse * _Nullable response, NSError * _Nullable error) { if (error) { NSLog(@"%@", error); return; } for (MKMapItem *mapItem in response.mapItems) { MKPointAnnotation *annotation = [[MKPointAnnotation alloc] init]; annotation.coordinate = mapItem.placemark.coordinate; annotation.title = mapItem.name; annotation.subtitle = mapItem.placemark.thoroughfare; [self.mapView addAnnotation:annotation]; } }]; } @end

这产生了:

demo


0
投票

这是一个基本的例子是几个步骤一样简单

1)添加以下注释中viewDidLoad会工作得很好

MKPointAnnotation *point1 = [[MKPointAnnotation alloc] init];
CLLocationCoordinate2D c1;
c1.latitude = 46.469391;
c1.longitude = 30.740883;
point1.coordinate = c1;
point1.title = @"Minsk, Belarus";
[self.mapView addAnnotation:point1];

MKPointAnnotation *point2 = [[MKPointAnnotation alloc] init];
CLLocationCoordinate2D c2;
c2.latitude = 46.469391;
c2.longitude = 30.740883;
point2.coordinate = c2;
point2.title = @"Odessa, Ukraine";
[self.mapView addAnnotation:point2];

2)在MapView类:MKMapViewDelegate的viewForAnnotation注解提供可重用的视图,如下所示:

- (MKAnnotationView *)mapView:(MKMapView *)mapView viewForAnnotation:(id <MKAnnotation>)annotation {
    if ([annotation isKindOfClass:[MKPointAnnotation class]]) {

        MKMarkerAnnotationView* annotationView = (MKMarkerAnnotationView *) (MKMarkerAnnotationView *)[_mapView dequeueReusableAnnotationViewWithIdentifier:@"Jacky.S"];
        if (annotationView == nil) {
            annotationView = [[MKMarkerAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:@"Jacky.S"];
            annotationView.enabled = YES;
            annotationView.clusteringIdentifier = @"pins";
            // annotationView.glyphImage = [UIImage imageNamed:@"we can use a nice image instead of the default pins"];
        } else {
            annotationView.annotation = annotation;
            annotationView.clusteringIdentifier = @"pins";
        }
        return annotationView;
    }
    return nil;
}

不要忘记设置MKMapViewDelegateUIViewController

[self.mapView setDelegate:self];

刚刚更新完张贴gist显示如何继承MKMarkerAnnotationView

© www.soinside.com 2019 - 2024. All rights reserved.