Nasıl MKAnnotationView kullanarak özel "pin-bırak" animasyon oluşturabilir?

oy
23

Ben bir örneğini sahip MKMapViewve özel açıklama simgeler yerine MKPinAnnotationView tarafından sağlanan standart raptiye simgelerini kullanmak istiyorum. Yani, kurulum ettik MKAnnotationView bir alt sınıf CustomMapAnnotation denilen ve geçersiz kılma ediyorum -(void)drawRect:bir CGImage çizmek. Bu çalışıyor.

Ben çoğaltmak çalıştığınızda sorun gelir .animatesDropMKPinAnnotationView tarafından sağlanan işlevselliği; Benim simgeler kademeli olarak görünmesi için isterdim, yukarıdan ve düştü soldan sağa ek açıklamaları eklendiğinde, sipariş MKMapViewörneği.

İşte - (void), drawRect: Sadece (2 hat yaptığı iştir) UIImage çizerken çalışır CustomMapAnnotation için:

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

Eklediğinizde sorun gelir animateDropyöntemi:

-(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:@];
}

Bu sadece çalışmıyor, ve bunun nedenleri bir sürü olabilir. Şimdi hepsi giremeyeceğim. Bildiğim isteyen ediyorum ana şey ben tamamen farklı bir şey denemek gerekir eğer yaklaşım hiç ses veya eğer olduğunu.

Ben BeginTime parametresi aslında işe yarayabilecek böylece bir animasyon işlem haline şeyi paketlemek için de çalıştı; bu hiç bir şey yapamaz gibiydi. Ben bazı temel nokta eksik am çünkü bu olup olmadığını bilmiyorum ya MapKit nasılsa animasyonlar kullanılamaz hale getiriyor çünkü olsun.

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

Herkes böyle animasyonlu MKMapAnnotations ile herhangi bir deneyim varsa, yaklaşım CAAnimation öneriler sunabilir, aksi takdirde, ben bazı ipuçları isteriz, bu çok iyi olur.

Oluştur 07/12/2009 saat 01:38
kaynak kullanıcı
Diğer dillerde...                            


5 cevaplar

oy
58

Paul Shapiro tarafından koduyla bir sorun, kullanıcı şu anda bakıyor yerin altındaki açıklamaları eklediğinizde başa olmamasıdır. Bu ek açıklamalar bunlar kullanıcının görülebilir harita rect'in taşındı çünkü düşmeden önce havada yüzer.

Bir diğeri de kullanıcı konum mavi nokta düşer olmasıdır. Aşağıda bu kod ile, kullanıcı yerini ve ekran dışı haritası ek açıklamaları büyük miktarlarda hem idare. Ben de güzel bir sıçrama ekledik;)

- (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;
                    }];
                }];
            }
        }];
    }
}
Cevap 12/08/2011 saat 21:24
kaynak kullanıcı

oy
52

Öncelikle, zaten yapmazsa görünümünüzü kontrolör MKMapViewDelegate uygulamak yapmak gerekir.

Ardından, bu yöntemi uygulamak:

- (void)mapView:(MKMapView *)mapView didAddAnnotationViews:(NSArray *)views { 
   MKAnnotationView *aV; 
   for (aV in views) {
     CGRect endFrame = aV.frame;

     aV.frame = CGRectMake(aV.frame.origin.x, aV.frame.origin.y - 230.0, aV.frame.size.width, aV.frame.size.height);

     [UIView beginAnimations:nil context:NULL];
     [UIView setAnimationDuration:0.45];
     [UIView setAnimationCurve:UIViewAnimationCurveEaseInOut];
         [aV setFrame:endFrame];
     [UIView commitAnimations];

   }
}

MapView etmek için ek açıklamalarınızı ekleyin ve onlar eklendiğinde, bu temsilci yöntemi çağrılır ve onlar eklendikçe yukarıdan aşağıya doğru işaretçilerine animasyon olacaktır.

zamanlama ve konumlandırma için değerler biraz değiştirilebilir ama iyi görünmesi için onu küçük değişiklikler yaptık / geleneksel damlasına kadar yakın (bildiğim kadarıyla test ettik gibi). Bu yardımcı olur umarım!

Cevap 18/01/2010 saat 16:52
kaynak kullanıcı

oy
12

Bir MKAnnotationView alt sınıfını yapıyorsanız Alternatif olarak, kullanabilirsiniz didMoveToSuperviewanimasyonu tetikleyecek. Aşağıdaki hafif 'ezmek' etkisi biten bir damla yapar

  #define kDropCompressAmount 0.1

  @implementation MyAnnotationViewSubclass

  ...

  - (void)didMoveToSuperview {
      CABasicAnimation *animation = [CABasicAnimation animationWithKeyPath:@"transform"];
      animation.duration = 0.4;
      animation.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseIn];
      animation.fromValue = [NSValue valueWithCATransform3D:CATransform3DMakeTranslation(0, -400, 0)];
      animation.toValue = [NSValue valueWithCATransform3D:CATransform3DIdentity];

      CABasicAnimation *animation2 = [CABasicAnimation animationWithKeyPath:@"transform"];
      animation2.duration = 0.10;
      animation2.beginTime = animation.duration;
      animation2.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseOut];
      animation2.toValue = [NSValue valueWithCATransform3D:CATransform3DScale(CATransform3DMakeTranslation(0, self.layer.frame.size.height*kDropCompressAmount, 0), 1.0, 1.0-kDropCompressAmount, 1.0)];
      animation2.fillMode = kCAFillModeForwards;

      CABasicAnimation *animation3 = [CABasicAnimation animationWithKeyPath:@"transform"];
      animation3.duration = 0.15;
      animation3.beginTime = animation.duration+animation2.duration;
      animation3.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseOut];
      animation3.toValue = [NSValue valueWithCATransform3D:CATransform3DIdentity];
      animation3.fillMode = kCAFillModeForwards;

      CAAnimationGroup *group = [CAAnimationGroup animation];
      group.animations = [NSArray arrayWithObjects:animation, animation2, animation3, nil];
      group.duration = animation.duration+animation2.duration+animation3.duration;
      group.fillMode = kCAFillModeForwards;

      [self.layer addAnimation:group forKey:nil];
  }
Cevap 26/06/2010 saat 19:56
kaynak kullanıcı

oy
5

Michael Tyson yanıt için ben tekrar animasyon yapar böylece MKAnnotationView doğru tekrar kullanım için didMoveToSuperview aşağıdaki kodun bir ekleme önermek ve sonra ek açıklamaların sequencial eklenmesini taklit (Henüz her yerde yorum yapamam)

Farklı görsel sonuçlar için bölücüler ve çarpanları ile oynayın ...

- (void)didMoveToSuperview {
    //necessary so it doesn't add another animation when moved to superview = nil
    //and to remove the previous animations if they were not finished!
    if (!self.superview) {
        [self.layer removeAllAnimations];
        return;
    }


    float xOriginDivider = 20.;
    float pos = 0;

    UIView *mySuperview = self.superview;
    while (mySuperview && ![mySuperview isKindOfClass:[MKMapView class]])
        mySuperview = mySuperview.superview;
    if ([mySuperview isKindOfClass:[MKMapView class]]) 
        //given the position in the array
        // pos = [((MKMapView *) mySuperview).annotations indexOfObject:self.annotation];   
        // left to right sequence;
        pos = [((MKMapView *) mySuperview) convertCoordinate:self.annotation.coordinate toPointToView:mySuperview].x / xOriginDivider;

    float yOffsetMultiplier = 20.;
    float timeOffsetMultiplier = 0.05;


    CABasicAnimation *animation = [CABasicAnimation animationWithKeyPath:@"transform"];
    animation.duration = 0.4 + timeOffsetMultiplier * pos;
    animation.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseIn];
    animation.fromValue = [NSValue valueWithCATransform3D:CATransform3DMakeTranslation(0, -400 - yOffsetMultiplier * pos, 0)];
    animation.toValue = [NSValue valueWithCATransform3D:CATransform3DIdentity];

    // rest of animation group...
}
Cevap 02/11/2010 saat 11:08
kaynak kullanıcı

oy
0

Ben daha iyi bir seçenek EVET 'animatesDrop' ayarlamak olduğunu düşünüyorum. Bu MKPinAnnotationView bir özelliği var.

Cevap 10/11/2014 saat 00:09
kaynak kullanıcı

Cookies help us deliver our services. By using our services, you agree to our use of cookies. Learn more