मैं कैसे MKAnnotationView उपयोग कर एक कस्टम "पिन ड्रॉप" एनीमेशन बना सकते हैं?

वोट
23

मैं का एक उदाहरण है MKMapViewऔर मानक पिन माउस MKPinAnnotationView द्वारा आपूर्ति की बजाय कस्टम एनोटेशन चिह्न का उपयोग करना चाहते हैं। MKAnnotationView का एक उपवर्ग CustomMapAnnotation कहा जाता है तो, मैं पहले से सेट किया और अधिभावी कर रहा हूँ -(void)drawRect:एक CGImage आकर्षित करने के लिए। यह काम।

मुसीबत आता है जब मैं दोहराने की कोशिश .animatesDropMKPinAnnotationView द्वारा आपूर्ति की कार्यक्षमता; मेरी माउस धीरे-धीरे प्रकट करने के लिए के लिए मैं प्यार होता है, ऊपर से और में गिरा बाएँ-से-सही क्रम, जब एनोटेशन में जुड़ जाते हैं MKMapViewउदाहरण।

यहाँ है - (शून्य) drawRect: CustomMapAnnotation है, जो काम करता है जब तुम सिर्फ UIImage (जो क्या 2 लाइन करता है) आकर्षित करने के लिए:

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

मुसीबत जब आप जोड़ना आता 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:@];
}

यह सिर्फ काम नहीं करता है, और कारण का एक बहुत हो सकता है। मैं उन सभी को में अब नहीं मिलेगा। मुख्य बात मैं जानना चाहता हूँ अगर दृष्टिकोण बिल्कुल आवाज़ है, या अगर मैं कुछ पूरी तरह से अलग की कोशिश करनी चाहिए है।

मैं एक एनीमेशन के लेनदेन में पूरी बात पैकेज करने के लिए इतना है कि beginTime पैरामीटर वास्तव में काम कर सकते हैं भी कोशिश की, इस सब पर कुछ भी नहीं लग रहा था। अगर इस वजह से मैं कुछ प्रमुख बिंदु याद आ रही है मैं नहीं जानता या क्या यह क्योंकि MapKit किसी भी तरह मेरी एनिमेशन trashing है।

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

अगर किसी को भी इस तरह एनिमेटेड MKMapAnnotations के साथ किसी भी अनुभव है, मैं, कुछ संकेत अच्छा लगेगा आप दृष्टिकोण पर CAAnimation सलाह की पेशकश कर सकते अन्यथा अगर, वह भी महान होगा।

07/12/2009 को 01:38
का स्रोत उपयोगकर्ता
अन्य भाषाओं में...                            


5 जवाब

वोट
58

पॉल शापिरो द्वारा कोड के साथ एक समस्या यह है कि यह जब तुम नीचे जहां उपयोगकर्ता पल में दिख रही है एनोटेशन जोड़ने के साथ सौदा नहीं करता है। उन एनोटेशन छोड़ने क्योंकि वे उपयोगकर्ता के दृश्यमान नक्शे RECT में ले जाया जाता है इससे पहले कि बीच हवा में तैर सकती है।

एक और यह भी उपयोगकर्ता स्थान नीले डॉट चला जाता है। नीचे इस कोड के साथ, आप उपयोगकर्ता स्थान और नक्शा एनोटेशन ऑफ स्क्रीन की बड़ी मात्रा में दोनों को संभाल। मैं भी एक अच्छा उछाल जोड़ दिया है;)

- (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;
                    }];
                }];
            }
        }];
    }
}
12/08/2011 को 21:24
का स्रोत उपयोगकर्ता

वोट
52

पहले, आप अपने दृश्य नियंत्रक को लागू MKMapViewDelegate यदि वह पहले से नहीं है बनाने की जरूरत है।

फिर, इस पद्धति को लागू:

- (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 करने के लिए अपने टिप्पणियां जोड़ें, और जब वे जुड़ जाते हैं, इस प्रतिनिधि विधि बुलाया जाएगा और के रूप में वे जोड़ रहे हैं ऊपर से नीचे तक पिंस चेतन होगा।

समय और स्थिति के लिए मूल्यों को एक छोटा सा बदला जा सकता है, लेकिन मैं यह सबसे अच्छा दिखने के लिए यह बदलाव किया है / पारंपरिक बूंद के सबसे करीब (जहाँ तक मैं परीक्षण किया है)। उम्मीद है की यह मदद करेगा!

18/01/2010 को 16:52
का स्रोत उपयोगकर्ता

वोट
12

वैकल्पिक रूप से, आप एक MKAnnotationView उपवर्ग बना रहे हैं, तो आप उपयोग कर सकते हैं didMoveToSuperviewएनीमेशन गति प्रदान करने के। निम्नलिखित एक बूंद कि एक मामूली 'तोड़ो' प्रभाव में समाप्त होता है करता है

  #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];
  }
26/06/2010 को 19:56
का स्रोत उपयोगकर्ता

वोट
5

माइकल टायसन की प्रतिक्रिया के लिए (मैं हर जगह अभी तक कोई टिप्पणी नहीं कर सकते हैं), मैं MKAnnotationView के समुचित पुनः उपयोग के लिए didMoveToSuperview में निम्न कोड की एक प्रविष्टि का प्रस्ताव तो यह एनीमेशन फिर से करता है और फिर टिप्पणियों का sequencial अलावा नकल

विभाजक और विभिन्न दृश्य परिणामों के लिए गुणकों के साथ खेलें ...

- (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...
}
02/11/2010 को 11:08
का स्रोत उपयोगकर्ता

वोट
0

मुझे लगता है कि बेहतर विकल्प हाँ करने के लिए 'animatesDrop' स्थापित करने के लिए है। यह MKPinAnnotationView की संपत्ति है।

10/11/2014 को 00:09
का स्रोत उपयोगकर्ता

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