如何创建自定义“pin-drop”按钮?使用MKAnnotationView动画? [英] How can I create a custom "pin-drop" animation using MKAnnotationView?

查看:137
本文介绍了如何创建自定义“pin-drop”按钮?使用MKAnnotationView动画?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有 MKMapView 的实例,并希望使用自定义注释图标而不是MKPinAnnotationView提供的标准图钉图标。所以,我设置了一个名为CustomMapAnnotation的MKAnnotationView的子类,并重写了 - (void)drawRect:来绘制CGImage。这很有效。

I have an instance of MKMapView and would like to use custom annotation icons instead of the standard pin icons supplied by MKPinAnnotationView. So, I've setup a subclass of MKAnnotationView called CustomMapAnnotation and am overriding -(void)drawRect: to draw a CGImage. This works.

当我尝试复制MKPinAnnotationView提供的 .animatesDrop 功能时出现问题。当注释被添加到 MKMapView 实例时,我希望我的图标能够逐渐显示,从上到下以及按从左到右的顺序显示。

The trouble comes when I try to replicate the .animatesDrop functionality supplied by MKPinAnnotationView; I would love for my icons to appear gradually, dropped from above and in left-to-right order, when the annotations are added to the MKMapView instance.

这是 - (void)drawRect:用于CustomMapAnnotation,当你只是绘制UIImage(这是第二行所做的)时可以工作:

Here is -(void)drawRect: for CustomMapAnnotation, which works when you just draw the UIImage (which is what the 2nd line does):

- (void)drawRect:(CGRect)rect {
 [super drawRect:rect];
 [((Incident *)self.annotation).smallIcon drawInRect:rect];
 if (newAnnotation) {
  [self animateDrop];
  newAnnotation = NO;
 }
} 

当您添加<$ c $时出现问题c> animateDrop 方法:

-(void)animateDrop {
 CGContextRef myContext = UIGraphicsGetCurrentContext();

 CGPoint finalPos = self.center;
 CGPoint startPos = CGPointMake(self.center.x, self.center.y-480.0);
 self.layer.position = startPos;

 CABasicAnimation *theAnimation;
 theAnimation=[CABasicAnimation animationWithKeyPath:@"position"];
 theAnimation.fromValue=[NSValue valueWithCGPoint:startPos];
 theAnimation.toValue=[NSValue valueWithCGPoint:finalPos];
 theAnimation.removedOnCompletion = NO;
 theAnimation.fillMode = kCAFillModeForwards;
 theAnimation.delegate = self;
 theAnimation.beginTime = 5.0 * (self.center.x/320.0);
 theAnimation.duration = 1.0;
 [self.layer addAnimation:theAnimation forKey:@""];
}

它只是不起作用,可能有很多原因可以解释为什么。我现在不会进入所有这些。我想知道的主要问题是这种方法是否合理,或者我应该尝试一些完全不同的方法。

It just doesn't work, and there could be a lot of reasons why. I won't get into all of them now. The main thing I am wanting to know is if the approach is sound at all, or if I should try something entirely different.

我还尝试打包整件事进入动画事务,以便beginTime参数可能实际工作;这似乎根本没有做任何事情。我不知道这是因为我错过了一些关键点,还是因为MapKit以某种方式破坏了我的动画。

I tried also to package up the whole thing into an animation transaction so that the beginTime parameter might actually work; this seemed to not do anything at all. I don't know if this is because I am missing some key point or whether it's because MapKit is trashing my animations somehow.

  // Does nothing
  [CATransaction begin];
  [map addAnnotations:list];
  [CATransaction commit];

如果有人有像这样的动画MKMapAnnotations的经验,我会喜欢一些提示,否则如果你可以提供有关该方法的CAAnimation建议,这也很棒。

If anyone has any experience with animated MKMapAnnotations like this, I'd love some hints, otherwise if you can offer CAAnimation advice on the approach, that'd be great too.

推荐答案

Paul Shapiro的代码存在的一个问题是当您在用户正在查看的位置下方添加注释时,它不会处理。这些注释会在下降之前浮动到半空中,因为它们被移动到用户的可见地图rect中。

One problem with the code by Paul Shapiro is that it doesn't deal with when you add annotations below where the user is looking at the moment. Those annotations will float in mid-air before dropping because they are moved into the user's visible map rect.

另一个是它也会丢弃用户位置蓝点。使用下面的代码,您可以在屏幕外处理用户位置和大量地图注释。我还添加了一个漂亮的反弹;)

Another is that it also drops the user location blue dot. With this code below, you handle both user location and large amounts of map annotations off-screen. I've also added a nice bounce ;)

- (void)mapView:(MKMapView *)mapView didAddAnnotationViews:(NSArray *)views {
    MKAnnotationView *aV; 

    for (aV in views) {

        // Don't pin drop if annotation is user location
        if ([aV.annotation isKindOfClass:[MKUserLocation class]]) {
            continue;
        }

        // Check if current annotation is inside visible map rect, else go to next one
        MKMapPoint point =  MKMapPointForCoordinate(aV.annotation.coordinate);
        if (!MKMapRectContainsPoint(self.mapView.visibleMapRect, point)) {
            continue;
        }

        CGRect endFrame = aV.frame;

        // Move annotation out of view
        aV.frame = CGRectMake(aV.frame.origin.x, aV.frame.origin.y - self.view.frame.size.height, aV.frame.size.width, aV.frame.size.height);

        // Animate drop
        [UIView animateWithDuration:0.5 delay:0.04*[views indexOfObject:aV] options:UIViewAnimationCurveLinear animations:^{

            aV.frame = endFrame;

        // Animate squash
        }completion:^(BOOL finished){
            if (finished) {
                [UIView animateWithDuration:0.05 animations:^{
                    aV.transform = CGAffineTransformMakeScale(1.0, 0.8);

                }completion:^(BOOL finished){
                    [UIView animateWithDuration:0.1 animations:^{
                        aV.transform = CGAffineTransformIdentity;
                    }];
                }];
            }
        }];
    }
}

这篇关于如何创建自定义“pin-drop”按钮?使用MKAnnotationView动画?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆