How to display title for multiple annotations directly when map loaded

对着背影说爱祢 提交于 2019-12-06 07:26:44
Paulw11

Update It does indeed seem that this isn't possible - at least not with the map view annotation APIs. Despite the existence of the select and deselect methods and the selected annotations property being an array, it seems that only a single annotation can be selected at a time.

It looks like you will need to create a custom annotation view as suggested in this answer - Multiple annotation callouts displaying in MKMapView

Nikolay Mamaev

According to the MKAnnotationView Class Reference, annotations callout bubbles appear & disappear upon change value of the selected property. The document states that developers "should not set the value of this property directly", however you can try :)

The first what I'd try is a simplest hacky way relying on that MKAnnotationView property. In your MKMapViewDelegate class, define the following method:

- (void)mapView:(MKMapView *)mapView didDeselectAnnotationView:(MKAnnotationView *)view
{
    view.selected = YES;
}

But I guess this may not work well because of visual artifacts upon tapping different annotations. If this is true, then the only proper way to achieve what you want is to create subclass of the MKAnnotationView which always displays a callout bubble regardless of a value of the selected property. Here are some tutorials on how to create a custom annotation view:

Update

Thanks to the @Paulw11's answer, I forgot to mention that to make the 'hacky' approach working, you need to set the select value for all annotations. This can be done in 3 ways:

  1. As per @Paulw11's answer (but this will not work for annotations outside of map's visible rectangle)
  2. Set the MKAnnotationView's selected property in your implementation of MKMapViewDelegate's mapView:viewForAnnotation: method (not sure if this will work)
  3. Set the MKAnnotationView's selected property for visible annotations each time when map view visible region changes.

With 3rd approach, I you'll need to implement the MKMapViewDelegate's mapView:regionDidChangeAnimated: method handling changes of map view visible region. Since this delegate method is called very often while a user is dragging or zooming in/out, it makes sense to defer actual update of annotation views until map view's visible region changes are over; to do this, I'd use NSTimer.

// In an interface or interface extension for MKMapViewDelegate class (guess this
// is your view controller), declare NSTimer and a method which will be executed
// when a user stops dragging or zooming
@property (nonatomic, strong) NSTimer* mapViewRegionChangeTimer;
- (void)mapViewRegionChangeCompleted:(NSTimer*)timer;


// In your implementation of MKMapViewDelegate:
- (void)mapView:(MKMapView *)mapView regionDidChangeAnimated:(BOOL)animated
{
    if (self.mapViewRegionChangeTimer != nil) {
        [self.mapViewRegionChangeTimer invalidate];
    }
    self.mapViewRegionChangeTimer = 
        [NSTimer scheduledTimerWithTimeInterval:0.2
                                         target:self
                                       selector:@selector(mapViewRegionChangeCompleted:)
                                       userInfo:nil
                                        repeats:NO];
}

- (void)mapViewRegionChangeCompleted:(NSTimer*)timer
{
    [self.mapViewRegionChangeTimer invalidate];
    self.mapViewRegionChangeTimer = nil;

    NSSet* visibleAnnotations = [self.map_View annotationsInMapRect:self.map_View.visibleMapRect];
    for (id<MKAnnotation> annotation in visibleAnnotations) {
        [self.map_View selectAnnotation:annotation animated:NO];
    }
}
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!