以下是我在不同大小的两个视图之间翻转和缩放的方法。我将动画分成几个部分。首先,我将后视图放在与前视图相同的位置,但将其隐藏。然后我翻转并缩放前视图的一半。后视图被赋予与前视图相同的变换,然后旋转并缩放其余部分。翻转基本上是相反的。
我想您可以使用不同的视图控制器视图属性作为后视图,但我没有尝试过。
// flip and scale frontView to reveal backView to the center of the screen
// uses a containerView to mark the end of the animation
// parameterizing the destination is an exercise for the reader
- (void)flipFromFront:(UIView*)frontView toBack:(UIView*)backView destination:(CGRect)destRect
{
float duration = 0.5;
// distance from center of screen from frontView
float dx = destRect.origin.x + CGRectGetWidth(destRect) / 2 - frontView.center.x;
float dy = destRect.origin.y + CGRectGetHeight(destRect) / 2 - frontView.center.y;
float scale = CGRectGetWidth(destRect) / CGRectGetWidth(frontView.bounds);
// this prevents any tearing
backView.layer.zPosition = 200.0;
// hide the backView and position where frontView is
backView.hidden = NO;
backView.alpha = 0.0;
backView.frame = frontView.frame;
// start the animation
[UIView animateKeyframesWithDuration:duration
delay:0.25
options:UIViewKeyframeAnimationOptionCalculationModeCubic
animations:^{
// part 1. Rotate and scale frontView halfWay.
[UIView addKeyframeWithRelativeStartTime:0.0
relativeDuration:0.5
animations:^{
// get the transform for the blue layer
CATransform3D xform = frontView.layer.transform;
// translate half way
xform = CATransform3DTranslate(xform, dx/2, dy/2, 0);
// rotate half way
xform = CATransform3DRotate(xform, M_PI_2, 0, 1, 0);
// scale half way
xform = CATransform3DScale(xform, scale/2, scale/2, 1);
// apply the transform
frontView.layer.transform = xform;
}];
// part 2. set the backView transform to frontView so they are in the same
// position.
[UIView addKeyframeWithRelativeStartTime:0.5
relativeDuration:0.0
animations:^{
backView.layer.transform = frontView.layer.transform;
backView.alpha = 1.0;
}];
// part 3. rotate and scale backView into center of container
[UIView addKeyframeWithRelativeStartTime:0.5
relativeDuration:0.5
animations:^{
// undo previous transforms with animation
backView.layer.transform = CATransform3DIdentity;
// animate backView into new location
backView.frame = destRect;
}];
} completion:^(BOOL finished) {
self.displayingFront = !self.displayingFront;
}];
}
// flip from back to front
- (void) flipFromBack:(UIView*)backView toFront:(UIView*)frontView
{
float duration = 0.5;
// get distance from center of screen to destination
float dx = backView.center.x - frontView.center.x;
float dy = backView.center.y - frontView.center.y;
backView.layer.zPosition = 200.0;
frontView.hidden = YES;
// this is basically the reverse of the previous animation
[UIView animateKeyframesWithDuration:duration
delay:0
options:UIViewKeyframeAnimationOptionCalculationModeCubic
animations:^{
[UIView addKeyframeWithRelativeStartTime:0.0
relativeDuration:0.5
animations:^{
CATransform3D xform = backView.layer.transform;
xform = CATransform3DTranslate(xform, -dx/2, -dy/2, 0);
xform = CATransform3DRotate(xform, M_PI_2, 0, 1, 0);
xform = CATransform3DScale(xform, 0.75, 0.75, 1);
backView.layer.transform = xform;
}];
[UIView addKeyframeWithRelativeStartTime:0.5
relativeDuration:0.0
animations:^{
backView.alpha = 0.0;
frontView.hidden = NO;
}];
[UIView addKeyframeWithRelativeStartTime:0.5
relativeDuration:0.5
animations:^{
self.hiddenView.alpha = 0.0;
frontView.layer.transform = CATransform3DIdentity;
}];
} completion:^(BOOL finished) {
self.displayingFront = !self.displayingFront;
}];
}