MKMapView, animateDrop?

14

我创建了一个NSMutableArray,其中包含从符合MKAnnotation协议的类派生的对象。我已经设置了注释的标题和副标题,并成功地将它们添加到了MKMapView中,使用以下代码:

[[self customMapView] addAnnotations:locationArray];

我现在想做的是使大头针动态掉落,最初我认为可以使用选项1来实现,虽然这样一切都正常,但大头针并没有动态掉落。

// Option1
// WORKS FOR: pinColor YES, animatesDrop NO, LABEL YES
- (void)mapView:(MKMapView *)mapView didAddAnnotationViews:(NSArray *)views {
    for(MKPinAnnotationView *eachView in views) {
        [eachView setAnimatesDrop:YES];
        [eachView setPinColor:MKPinAnnotationColorPurple];
    }
}

我的下一个猜想是尝试Option2,这似乎非常有效,但我有两个问题。 标题和副标题不显示,我的自定义注释对象被传递进去了(我可以在调试器中看到它),但其中包含的信息没有传递到新的pin。其次,这会创建一组新的MKAnnotationViews,旧的MKAnnotationViews会发生什么情况?会有任何内存泄漏的问题吗?

// Option2
//FOR: pinColor YES, animatesDrop YES, LABEL NO
- (MKAnnotationView *) mapView: (MKMapView *) mapView viewForAnnotation: (id<MKAnnotation>) annotation {
    MKPinAnnotationView *pin = (MKPinAnnotationView *) [mapView dequeueReusableAnnotationViewWithIdentifier: @"annotation_ID"];
    if (pin == nil) {
        pin = [[[MKPinAnnotationView alloc] initWithAnnotation: annotation reuseIdentifier: @"annotation_ID"] autorelease];
    } else {
        pin.annotation = annotation;
    }
    pin.pinColor = MKPinAnnotationColorRed;
    pin.animatesDrop = YES;
    return pin;
}

编辑:我通过添加pin.canShowCallout = YES;解决了标题和副标题消失的问题。


1
在您的第二个选项代码中,当创建引脚时它不会有注释设置。我会删除“else”并缩进pin.annotation = annotation这一行,以便它总是被设置。 - theLastNightTrain
3个回答

32

MKPinAnnotationView是MKAnnotationView的子类。

MKAnnotationView是通用的注释视图,您需要提供图像和所需的动画。

MKPinAnnotationView是MKAnnotationView的方便子类,它自动提供选定颜色的引脚图像和引脚落在地图上的动画。在viewForAnnotation中创建视图时设置animatesDrop属性,它将从那里自动处理动画。

如果您没有实现viewForAnnotation,则显示一个标准的红色引脚而没有动画。

当调用didAddAnnotationViews时,自动动画已经发生,设置该属性不起作用。

但是,如果您想创建与MKPinAnnotationView提供的默认下降动画不同的自定义动画,则可以在didAddAnnotationViews中执行此操作。视图已经到达其最终目的地,因此您可以保存它,然后从不同的点向该目的地进行动画处理。

如果您满意MKPinAnnotationView提供的默认下降动画,则无需实现didAddAnnotationViews。该委托方法更有用的是在所有注释视图实际放置时执行其他需要执行的操作。

为了显示标题,将canShowCallout设置为YES,并在设置animatesDrop的地方进行设置。

不确定您所说的“这将创建一组新的MKAnnotationViews”是什么意思。在viewForAnnotation方法中,您为MKAnnotation对象提供了一个视图(MKPinAnnotationView)。它们不是同一件事。

此外,viewForAnnotation方法的工作方式类似于UITableView的cellForRowAtIndexPath方法,其中注释视图可以被回收,这就是为什么每次都要在视图中设置MKAnnotation特定信息(例如注释属性)的重要性。


非常感谢aBitObvoius,您的回答非常完美。关于MKAnnotationViews,我曾经误以为如果您不实现viewForAnnotation(在其中获取默认的红色标记),那么可能已经在某个地方创建了MKAnnotationView,并且随后实现它时,我可能需要对旧的进行一些处理,因此感到有些困惑。 - fuzzygoat
通过实现viewForAnnotation,您正在覆盖默认视图,因此不会出现重复。 - user467105

11

这是我能找到的最简单的解决方案。它在viewDidLoad事件中在UIMapView上放置了一个单独的标记。

  1. 项目需要引用MapKit框架

  2. 视图需要包含以下导入:#import <MapKit/MapKit.h>

  3. 视图控制器需要实现MKMapViewDelegate协议

  4. 视图控制器实现应包含:

- (MKAnnotationView *) mapView:(MKMapView *)mapView viewForAnnotation:(id ) annotation
{
    MKPinAnnotationView *newAnnotation = [[MKPinAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:@"annotation1"];
    newAnnotation.pinColor = MKPinAnnotationColorGreen;
    newAnnotation.animatesDrop = YES; 
    newAnnotation.canShowCallout = NO;
    [newAnnotation setSelected:YES animated:YES]; 
    return newAnnotation;
}
  1. viewDidLoad包含以下内容:
CLLocationCoordinate2D geos = CLLocationCoordinate2DMake(0.2344, 45.324);
MKPlacemark* marker = [[MKPlacemark alloc] initWithCoordinate:geos addressDictionary:nil];
[mapView addAnnotation:marker];
[marker release];

1
在 viewForAnnotation: 方法中,你应该使用 mapView.dequeueReusableAnnotationViewWithIdentifier 方法,就像在 tableView 中使用 dequeueReusableCellWithIdentifier 方法一样。否则,你会不断地创建具有未实际重用的重用标识符的 MKAnnotations。 - Frederic Adda
你在viewForAnnotation中选择了注释,这似乎毫无意义。 - pronebird

0

更新Swift3:

 func mapView(_ mapView: MKMapView, viewFor annotation: MKAnnotation) -> MKAnnotationView? {

  if annotation is MKUserLocation {
     return nil
  }

  let pinAnnotation = MKPinAnnotationView(annotation: annotation, reuseIdentifier: "PinAnnotation")
  pinAnnotation.pinTintColor = .green;
  pinAnnotation.animatesDrop = true;
  pinAnnotation.canShowCallout = false;
  pinAnnotation.setSelected(true, animated: true)

  return pinAnnotation
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接