简体   繁体   中英

Animating UIView origin only works after first try

I have a UIView with some labels in it I built in my storyboard that I want to animate when a map annotation is clicked. I have everything working great except the animations are a bit off. The first time you click an annotation the frame position is not animated. But if I deselect and then reselect the annotation it animates fine from then on. I also animate the background color and that seems to be working fine on the first select so whatever it is is peculiar to the frame property, perhaps because it's no set up appropriately at load? Again I did all that in the storyboard so I don't know what I'm missing.

Code for my Labels/View (all built in my storyboard and using reference outlets to the proper IBOutlets). file.h:

@property (weak, nonatomic) IBOutlet UIView *stationinfo;
@property (weak, nonatomic) IBOutlet UILabel *stationname;
@property (weak, nonatomic) IBOutlet UILabel *stationsong;
@property (weak, nonatomic) IBOutlet UILabel *stationartist;

file.m:

@synthesize stationinfo;
@synthesize stationname;
@synthesize stationsong;
@synthesize stationartist;

Please find code for callbacks below:

- (void) mapView:(MKMapView *)mapView didSelectAnnotationView:(MKAnnotationView *)view {
    //NSLog(@"Selected ");
    self.stationname.text = ((userStation *)view.annotation).name;
    self.stationsong.text = ((userStation *)view.annotation).song;
    self.stationartist.text = ((userStation *)view.annotation).artist;
    [UIView
     animateWithDuration:0.25
     delay: 0.0
     options: UIViewAnimationCurveEaseInOut
     animations:^ {
        CGRect anim = self.stationinfo.frame;
        anim.origin.y = 0.0;
        self.stationinfo.frame = anim;
        self.stationinfo.backgroundColor = [UIColor redColor];
    }
     completion:^(BOOL finished){
         NSLog(@"DONE!");
     }];
}

- (void) mapView:(MKMapView *)mapView didDeselectAnnotationView:(MKAnnotationView *)view {
    //NSLog(@"Deselected");
    [UIView
     animateWithDuration:0.25
     delay: 0.0
     options: UIViewAnimationCurveEaseInOut
     animations:^ {
         CGRect anim = self.stationinfo.frame;
         anim.origin.y = -100.0;
         self.stationinfo.frame = anim;
         self.stationinfo.backgroundColor = [UIColor greenColor];
     }
     completion:^(BOOL finished){
         NSLog(@"DONE!");
     }];
}

Your help is much appreciated. Thank you.

EDIT: While the below worked before, I found that it was in fact no longer necessary! I can only imagine I inadvertently fixed the bug in adjusting my storyboard the other day when I was applying appropriate constraints and such to my layout to ensure it looked good on the new screen size.

The work around I found was to perform the animation again in the complete function. While inelegant it seems to work (since only the first animation call doesn't work this second one on complete does it again). Note this will cause a delay since the first try has to complete first. I'm guessing there's some property of frames that is initialized by the first animation which is required to animate the position.

[UIView
         animateWithDuration:0.25
         delay: 0.0
         options: UIViewAnimationCurveEaseInOut
         animations:^ {
            CGRect anim = self.stationinfo.frame;
            anim.origin.y = 0.0;
            self.stationinfo.frame = anim;
        }
        completion:^(BOOL finished){
            CGRect anim = self.stationinfo.frame;
            anim.origin.y = 0.0;
            self.stationinfo.frame = anim;
        }];

I guess alternatively one could fire a neutral animation before the main one as well to see if that has the same effect.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM