简体   繁体   中英

Slide and Rotate UIView

I am trying to slide in a UIView while also rotating it. The end result is basically a UIView that zips across the screen rotating about 70 degrees to the left, hits the edge, rotates about 50 degrees to the right, and finally ends up being still (after a few more wobbles). I am able to get it sliding and rotating, but when I try to animate the second rotation (once it hits the edge), the frame goes back to the original value (back to the left of the screen). How do I get the frame to stick once the UIView has slid across?

[UIView animateWithDuration:.4 delay:0.0 
                    options:UIViewAnimationCurveEaseInOut
                 animations:^{
                     CGAffineTransform slideAndRotate = CGAffineTransformMakeTranslation(300, 0);
                     slideAndRotate = CGAffineTransformRotate(slideAndRotate, RADIANS(75));

                     self.ticketImageView.transform = slideAndRotate;                 
} completion:^(BOOL finished) {
    // set the frame to the location where it ended up
    NSLog(@"%@", NSStringFromCGRect(self.ticketImageView.frame));
    [UIView animateWithDuration:.35 
                          delay:0.05 
                        options:UIViewAnimationCurveEaseInOut 
     | UIViewAnimationOptionBeginFromCurrentState
                     animations:^{
                         CGAffineTransform rightAngle1 = 
                         CGAffineTransformRotate(CGAffineTransformIdentity, RADIANS(-45.0));
                         [[self ticketImageView] setTransform:rightAngle1];
    } completion:^(BOOL finished) {

    }];

In your first animation block, you are creating transform that includes both a translation and a rotation. In your second animation block, you are creating a transform that includes a rotation but not a translation. So your view is no longer translated when you animate to the second transform.

I see that you have used the UIViewAnimationOptionBeginFromCurrentState option. You might think this option makes the second transform stack with the first, but it doesn't. The second transform replaces the first, regardless of the option.

A UIView has two properties that affect its location. One is transform , which you are using. The other is center .

Usually we use the center property to move a view around, and only use the transform property to rotate and scale the view. I recommend you do the same.

Since you say you want the view to wobble a few more times, I suggest you try something like this:

- (void)viewDidAppear:(BOOL)animated {
    [super viewDidAppear:animated];

    [UIView animateWithDuration:0.4 animations:^{
        self.ticketImageView.center = CGPointMake(180, self.ticketImageView.center.y);
    }];

    [self wobbleWithAmount:0.4 direction:1];
}

- (void)wobbleWithAmount:(CGFloat)amount direction:(CGFloat)direction {
    [UIView animateWithDuration:amount animations:^{
        self.ticketImageView.transform = CGAffineTransformMakeRotation(amount * direction * M_PI * 0.5f);
    } completion:^(BOOL finished) {
        if (amount > 0.05f) {
            [self wobbleWithAmount:amount * 0.5f direction:-direction];
        } else {
            [UIView animateWithDuration:amount * 0.5f animations:^{
                self.ticketImageView.transform = CGAffineTransformIdentity;
            }];
        }
    }];
}

When you create the second transform rightAngle1 , you should be using [[self ticketImageView] transform] instead of CGAffineTransformIdentity . Using the identity transform, you basically erase the first transform and start from scratch.

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