Πώς μπορώ να δημιουργήσω ένα προσαρμοσμένο «pin-drop» κινούμενα σχέδια, χρησιμοποιώντας MKAnnotationView;

ψήφοι
23

Έχω μια περίπτωση MKMapViewκαι θα ήθελαν να χρησιμοποιήσουν εικόνες έθιμο σχολιασμό αντί των κατ 'αποκοπή εικονίδια pin που παρέχεται από MKPinAnnotationView. Έτσι, έχω να στήσετε μια υποκατηγορία των MKAnnotationView ονομάζεται CustomMapAnnotation και είμαι επιτακτικούς -(void)drawRect:να σχεδιάσετε ένα CGImage. Αυτό λειτουργεί.

Το πρόβλημα έρχεται όταν προσπαθώ να αναπαράγουν τη .animatesDropλειτουργικότητα που παρέχεται από MKPinAnnotationView? Θα ήθελα πολύ για τις εικόνες μου να εμφανίζονται σταδιακά, έπεσε από πάνω και από αριστερά προς τα δεξιά ώστε, όταν οι σχολιασμοί προστίθενται στο 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 έχει διαλύσει κινήσεις μου με κάποιο τρόπο.

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

Αν κάποιος έχει κάποια εμπειρία με κινούμενα MKMapAnnotations όπως αυτό, θα ήθελα κάποιες συμβουλές, αλλιώς αν μπορείτε να προσφέρετε CAAnimation συμβουλές σχετικά με την προσέγγιση, ότι θα ήταν πάρα πολύ μεγάλη.

Δημοσιεύθηκε 07/12/2009 στις 01:38
πηγή χρήστη
Σε άλλες γλώσσες...                            


5 απαντήσεις

ψήφοι
58

Ένα πρόβλημα με τον κωδικό από τον Paul Shapiro είναι ότι δεν ασχολείται με όταν προσθέτετε σχόλια κάτω από όπου ο χρήστης ψάχνει αυτή τη στιγμή. Αυτά τα σχόλια θα επιπλέουν στον αέρα πριν από την πτώση, επειδή κινούνται σε ορατό ορθ χάρτη του χρήστη.

Ένας άλλος λόγος είναι ότι πέφτει, επίσης, τη θέση του χρήστη μπλε κουκίδα. Με αυτόν τον παρακάτω κώδικα, θα χειριστεί τόσο την τοποθεσία του χρήστη και μεγάλες ποσότητες χάρτη σχολιασμούς εκτός οθόνης. Έχω προσθέσει επίσης ένα ωραίο αναπήδηση?)

- (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για να προκαλέσει την κίνηση. Η ακόλουθη κάνει μια πτώση που καταλήγει σε μια μικρή «squish» φαινόμενο

  #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

Για απάντηση του Michael Tyson (που δεν μπορώ να σχολιάσω παντού ακόμα), προτείνω την εισαγωγή του παρακάτω κώδικα στο didMoveToSuperview για την ορθή επαναχρησιμοποίηση των MKAnnotationView έτσι ώστε να κάνει και πάλι την κίνηση και στη συνέχεια να μιμηθούν το 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» σε YES. Είναι μια ιδιότητα του 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