如何在带有圆角的超视图中翻转非全屏UIView?

时间:2012-05-23 20:29:45

标签: ios core-animation

我正在翻转UIViews类似于Weather应用程序的页面翻转。但是,视图不是全屏视图,并且superview具有圆角。问题是在翻转动画期间,超视图的圆角用黑色填充到方角。

以下是我设置角落的方式:

self.view.layer.cornerRadius = 15.0f;
self.view.clipsToBounds = YES;

以下是我翻转视图的方式(保留frontViewbackView):

UIView *toView;
UIView *fromView;
UIViewAnimationOptions animationType;

if (toFront) {
    toView = self.frontView;
    fromView = self.backView;
    animationType = UIViewAnimationOptionTransitionFlipFromLeft;
} else {
    toView = self.backView;
    fromView = self.frontView;
    animationType = UIViewAnimationOptionTransitionFlipFromRight;
}

[UIView transitionFromView:self.fromView
                    toView:self.toView
                  duration:1
                   options:animationType
                completion:nil];

当我这样做时,self.view的圆角被填充到黑色的矩形边角。这可以避免吗?我不认为我对Core Animation有足够的了解来解决这个问题。

2 个答案:

答案 0 :(得分:5)

如果您需要在Core Animation中执行此操作,您可以通过单独制作动画来替换视图来实现。这并不难。下面是如何操作以及一些示例代码的说明:

替换视图

替换视图可以使用以下方式完成:

[UIView transitionFromView:self.fromView
                    toView:self.toView
                  duration:0.0
                   options:UIViewAnimationOptionTransitionNone
                completion:nil];

动画翻转

困难的部分显然是动画(如果你以前从未这样做的话,将它们放在一起)。

仅显示两个视图的正面

由于您想要将两个视图翻转为好像它们是一张纸的两面,因此当它们面向远方时,您不希望它们中的任何一个出现。这是通过在两个图层上将doubleSided属性设置为NO来完成的。 (不是双面意味着单面)。

翻转

您希望将前视图的变换从身份变换(无变换)设置为围绕y轴旋转180度(面向后),以便从左向右翻转。

同时,您希望将后视图的变换从 -180度旋转设置为身份变换。这将使翻转。这两种动画都可以作为“基本”动画来完成:

CABasicAnimation *flipAnimation = [CABasicAnimation animationWithKeyPath:@"transform"];
[flipAnimation setFromValue:[NSValue valueWithCATransform3D:CATransform3DIdentity]]; // No rotation
[flipAnimation setToValue:[NSValue valueWithCATransform3D:CATransform3DMakeRotation(M_PI, 0,1,0)]]; // Rotate PI around Y
[flipAnimation setFillMode:kCAFillModeBoth];
[flipAnimation setRemoveOnCompletion:NO];
[flippingView layer] addAnimation:flipAnimation forKey:@"myFlipAnimation"];

然后,您为另一个视图执行相同类型的动画。 (填充模式可防止动画在完成后跳回其原始状态)

全部放在一起

由于您希望两个动画同时运行并希望在动画结束时运行视图替换代码,因此您可以使用动画事务。这也允许您配置两个动画在一个地方的显示方式:

[CATransaction begin];
[CATransaction setAnimationDuration:2.0]; // 2 seconds
[CATransaction setAnimationTimingFunction:[CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut]];
[CATransaction setCompletionBlock:^{
    // Your view replacing code here...
}];
// Add the animations to both views here...
[CATransaction commit];

答案 1 :(得分:0)

这是我写完的内容。似乎工作正常,但是,当然,自己测试一下。

注意事项:

  • 在调用此视图之前,您应该添加要为其设置动画的视图 方法。

  • 该方法不会删除任何视图,因此请删除它们 必要时用完成块。

  • 该方法也没有 修改视图的“图层模型”值,使它们保持不变 他们是在动画之后。

`

+ (void)flipRight:(BOOL)flipRight fromView:(UIView *)fromView toView:(UIView *)toView duration:(NSTimeInterval)duration completion:(void (^)(void))completionBlock {

// Save original values
BOOL fromViewDoubleSided = fromView.layer.doubleSided;
BOOL toViewDoubleSided = toView.layer.doubleSided;
BOOL fromViewUserInteractionEnabled = fromView.userInteractionEnabled;
BOOL toViewUserInteractionEnabled = toView.userInteractionEnabled;

// We don't want to see the other side of the layer
fromView.layer.doubleSided = NO;
toView.layer.doubleSided = NO;

// We don't want user to fire off animation while its already going
fromView.userInteractionEnabled = NO;
toView.userInteractionEnabled = NO;

[CATransaction begin];

[CATransaction setCompletionBlock:^{

    // Restore original values
    fromView.layer.doubleSided = fromViewDoubleSided;
    toView.layer.doubleSided = toViewDoubleSided;
    fromView.userInteractionEnabled = fromViewUserInteractionEnabled;
    toView.userInteractionEnabled = toViewUserInteractionEnabled;

    if (completionBlock) completionBlock();
}];

CATransform3D flipOutTransform3D = CATransform3DMakeRotation(M_PI, 0,1,0);
flipOutTransform3D.m34 = 1.0/(300.0*(flipRight ? -1 : 1));
CABasicAnimation *flipOutAnimation = [CABasicAnimation animationWithKeyPath:@"transform"];
flipOutAnimation.fromValue = [NSValue valueWithCATransform3D:CATransform3DIdentity];
flipOutAnimation.toValue = [NSValue valueWithCATransform3D:flipOutTransform3D];
flipOutAnimation.duration = duration;

CATransform3D flipInTransform3D = CATransform3DMakeRotation(M_PI, 0,1,0);
flipInTransform3D.m34 = 1.0/(300.0*(flipRight ? 1 : -1));
CABasicAnimation *flipInAnimation = [CABasicAnimation animationWithKeyPath:@"transform"];
flipInAnimation.fromValue = [NSValue valueWithCATransform3D:flipInTransform3D];
flipInAnimation.toValue = [NSValue valueWithCATransform3D:CATransform3DIdentity];
flipInAnimation.duration = duration;


[fromView.layer addAnimation:flipOutAnimation forKey:@"flipOutAnimation"];
[toView.layer addAnimation:flipInAnimation forKey:@"flipInAnimation"];

[CATransaction commit];
};