30

viewForAnnotation で自分のイメージを設定するカスタム MKAnnotationView があります。MKPinAnnotationView でできるようにドロップをアニメーション化するにはどうすればよいですか?

私のコードは

- (MKAnnotationView *)mapView:(MKMapView *)map viewForAnnotation:(id <MKAnnotation>)annotation
{
    static NSString *AnnotationViewID = @"annotationViewID";

    MKAnnotationView *annotationView = (MKAnnotationView *)[mapView dequeueReusableAnnotationViewWithIdentifier:AnnotationViewID];

    if (annotationView == nil)
    {
        annotationView = [[[MKAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:AnnotationViewID] autorelease];
    }

    annotationView.image = [UIImage imageNamed:@"blah.png"];
    annotationView.annotation = annotation;

    return annotationView;
}
4

7 に答える 7

57

Anna Karenina による上記のコードの問題の 1 つは、ユーザーが現在見ている場所の下に注釈を追加するときに処理されないことです。これらの注釈は、ドロップする前に空中に浮かびます。これは、ユーザーの目に見えるマップの四角形に移動されるためです。

もう1つは、ユーザーの場所の青い点もドロップすることです. 以下のコードを使用すると、ユーザーの位置情報と大量のマップ アノテーションの両方を画面外で処理できます。素敵なバウンスも追加しました ;)

- (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: UIViewAnimationOptionCurveLinear 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){
                    if (finished) {
                        [UIView animateWithDuration:0.1 animations:^{
                            aV.transform = CGAffineTransformIdentity;
                        }];
                    }
                }];
            }
        }];
    }
}
于 2011-08-12T20:20:59.183 に答える
48

デリゲート メソッドを実装し、didAddAnnotationViews自分でアニメーションを実行します。

- (void)mapView:(MKMapView *)mapView 
          didAddAnnotationViews:(NSArray *)annotationViews
{
    for (MKAnnotationView *annView in annotationViews)
    {
        CGRect endFrame = annView.frame;
        annView.frame = CGRectOffset(endFrame, 0, -500);
        [UIView animateWithDuration:0.5 
                animations:^{ annView.frame = endFrame; }];
    }
}
于 2011-07-24T20:23:07.560 に答える
8

@MrAlekのswift3の回答

optional func mapView(_ mapView: MKMapView, didAdd views: [MKAnnotationView]) {
    print(#function)

    var i = -1;
    for view in views {
        i += 1;
        if view.annotation is MKUserLocation {
            continue;
        }

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

        let endFrame:CGRect = view.frame;

        // Move annotation out of view
        view.frame = CGRect(origin: CGPoint(x: view.frame.origin.x,y :view.frame.origin.y-self.view.frame.size.height), size: CGSize(width: view.frame.size.width, height: view.frame.size.height))

        // Animate drop
        let delay = 0.03 * Double(i)
        UIView.animate(withDuration: 0.5, delay: delay, options: UIViewAnimationOptions.curveEaseIn, animations:{() in
            view.frame = endFrame
            // Animate squash
            }, completion:{(Bool) in
                UIView.animate(withDuration: 0.05, delay: 0.0, options: UIViewAnimationOptions.curveEaseInOut, animations:{() in
                    view.transform = CGAffineTransform(scaleX: 1.0, y: 0.6)

                    }, completion: {(Bool) in
                        UIView.animate(withDuration: 0.3, delay: 0.0, options: UIViewAnimationOptions.curveEaseInOut, animations:{() in
                            view.transform = CGAffineTransform.identity
                            }, completion: nil)
                })

        })
    }
}
于 2016-11-09T02:37:23.117 に答える
5

Swift 2での@MrAlekの答え:

func mapView(mapView: MKMapView, didAddAnnotationViews views: [MKAnnotationView]) {
    print(__FUNCTION__)

    var i = -1;
    for view in views {
        i++;
        if view.annotation is MKUserLocation {
            continue;
        }

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

        let endFrame:CGRect = view.frame;

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

        // Animate drop
        let delay = 0.03 * Double(i)
        UIView.animateWithDuration(0.5, delay: delay, options: UIViewAnimationOptions.CurveEaseIn, animations:{() in
            view.frame = endFrame
            // Animate squash
            }, completion:{(Bool) in
                UIView.animateWithDuration(0.05, delay: 0.0, options: UIViewAnimationOptions.CurveEaseInOut, animations:{() in
                    view.transform = CGAffineTransformMakeScale(1.0, 0.6)

                    }, completion: {(Bool) in
                        UIView.animateWithDuration(0.3, delay: 0.0, options: UIViewAnimationOptions.CurveEaseInOut, animations:{() in
                            view.transform = CGAffineTransformIdentity
                            }, completion: nil)
                })

        })
    }
}
于 2016-01-23T18:30:29.050 に答える