Animation of CGAffineTransform in iOS8 looks different than in iOS7

前端 未结 6 1841
南方客
南方客 2021-02-02 11:59

I\'m trying to find a reason why animation of UIView transform property looks different in iOS 8 than iOS 6/7.

For a simple example, prior to iOS 8:

6条回答
  •  无人及你
    2021-02-02 12:51

    This isn't entirely related, but I was struggling with CGAffineTransformScale not working at all on iOS7 in a fairly complicated animation. It turns out my problem was iOS7 cannot calculate CGAffineTransformScale with CGAffineTransformRotate at the same time. In iOS7, the last animation call you make is the only one that gets animated, so only the rotation was occurring. This bug is fixed in iOS8.

    My solution is to simplify my animation for iOS7, only turning on the fancy stuff in iOS8:

    //Pre-animation setup:
    CGFloat radians = (M_PI/180) * (-15);  //Get a human-readable number in degrees
    self.badgeImage.alpha = 0;  //Start the image as invisible
    self.badgeImage.transform = CGAffineTransformScale(self.badgeImage.transform, 1.5, 1.5);  //Start the image as scaled bigger than normal
    if(NSFoundationVersionNumber > NSFoundationVersionNumber_iOS_7_1) {  //See below. We will not be rotating the image in iOS7
        self.badgeImage.transform = CGAffineTransformRotate(self.badgeImage.transform, radians);  //Rotate the image if iOS8
    }
    
    //Animation Pieces:
    //Fade in
    [UIView animateWithDuration: 0.5
                    delay:0
                    options:0
                    animations:^{
                        self.badgeImage.alpha = 1.0f; //Return image to opaque
                    }
                    completion:NULL];
    //Scale with bounce
    [UIView animateWithDuration: 1.1
                    delay:0
                    usingSpringWithDamping:0.3  //Not as good as Android's bounce interpolator, but I'll take it
                    initialSpringVelocity:-1.0f //A negative velocity here makes the animation appear more like gravity than spring
                    options:0
                    animations:^{
                        self.badgeImage.transform = CGAffineTransformScale(self.badgeImage.transform, 0.67, 0.67);  //Return image to its original size. These arguments are relative to its current scale.
                    }
                    completion:NULL];
    //Rotation
    if(NSFoundationVersionNumber > NSFoundationVersionNumber_iOS_7_1) { //This second animation call negates the first one on iOS7, so remove it.
        [UIView animateWithDuration: 0.9
                        delay:0
                        options:UIViewAnimationOptionCurveEaseOut
                        animations:^{
                            self.badgeImage.transform = CGAffineTransformRotate(self.badgeImage.transform, (radians * -1)); //Rotate the image back to its original orientation if iOS8
                        }
                        completion:NULL];
    }
    

    Of course, you can still combine multiple effects in iOS7 if you use the confusingly-named CGAffineTransformMakeScale() function. For instance, in the pre-animation setup, you can set both a rotation AND a scale, then set call CGAffineTransformMakeScale(1,1) to reset the image to its original metrics (MakeScale's arguments are specific, not relative - even more confusing!). This isn't always preferable, such as my example above where "bouncing" the animation would also bounce the rotation.

提交回复
热议问题