如何动画UIImageViews,如舱门打开

时间:2012-02-04 01:19:19

标签: ios uiimageview uiviewanimation

我正在尝试创建一个看起来像是朝向用户的2扇法式门(或2个舱门)的动画。

我尝试使用内置的UIViewAnimationOptionTransitionFlipFromRight转换,但转换的原点似乎是UIImageView的中心而不是左边缘。基本上我有2个UIImageViews,每个填充都有屏幕。我希望动画看起来像UIImageViews从屏幕中心提升到边缘。

[UIView transitionWithView:leftView
                  duration:1.0
                   options:UIViewAnimationOptionTransitionFlipFromRight                           
                animations:^ { leftView.alpha = 0; }
                completion:^(BOOL finished) {
                    [leftView removeFromSuperview]; 
                }];

以前有人做过这样的事吗?任何帮助都会很棒!

更新: 尼克洛克伍德的工作代码

leftView.layer.anchorPoint = CGPointMake(0, 0.5); // hinge around the left edge
leftView.frame = CGRectMake(0, 0, 160, 460); //reset view position

rightView.layer.anchorPoint = CGPointMake(1.0, 0.5); //hinge around the right edge
rightView.frame = CGRectMake(160, 0, 160, 460); //reset view position

[UIView animateWithDuration:0.75 animations:^{
    CATransform3D leftTransform = CATransform3DIdentity;
    leftTransform.m34 = -1.0f/500; //dark magic to set the 3D perspective
    leftTransform = CATransform3DRotate(leftTransform, -M_PI_2, 0, 1, 0);
    leftView.layer.transform = leftTransform;

    CATransform3D rightTransform = CATransform3DIdentity;
    rightTransform.m34 = -1.0f/500; //dark magic to set the 3D perspective
    rightTransform = CATransform3DRotate(rightTransform, M_PI_2, 0, 1, 0);
    rightView.layer.transform = rightTransform;
}];

1 个答案:

答案 0 :(得分:26)

首先将QuartzCore库添加到项目中#import <QuartzCore/QuartzCore.h>

每个视图都有一个layer属性,其子属性是可动画的。在动画功能方面,你可以找到所有非常酷的东西(我建议你阅读你可以设置的CALayer类属性 - 它会让你大吃一惊 - 任何视图上都有动态柔和的阴影效果? )

无论如何,回到话题。要以3D方式打开门,首先将它们放置为关闭,这样每扇门都会填满屏幕的一半。

现在将view.layer.anchorPoint属性设置如下

leftDoorView.layer.anchorPoint = CGPoint(0, 0.5); // hinge around the left edge
rightDoorView.layer.anchorPoint = CGPoint(1.0, 0.5); // hinge around the right edge

现在应用以下动画

[UIView animateWithDuration:0.5 animations:^{
   CATransform3D leftTransform = CATransform3DIdentity;
   leftTransform.m34 = -1.0f/500; //dark magic to set the 3D perspective
   leftTransform = CATransform3DRotate(leftTransform, M_PI_2, 0, 1, 0); //rotate 90 degrees about the Y axis
   leftDoorView.layer.transform = leftTransform;
   //do the same thing but mirrored for the right door, that probably just means using -M_PI_2 for the angle. If you don't know what PI is, Google "radians"
}];

那应该这样做。

免责声明:我实际上没有对此进行测试,因此角度可能会向后倾斜,视角可能会变得棘手等等,但它至少应该是一个好的开始。

更新:好奇心让我变得更好。这是完全正常工作的代码(这假设左右门在nib文件中的关闭位置布局):

- (void)viewDidLoad
{
    [super viewDidLoad];

    leftDoorView.layer.anchorPoint = CGPointMake(0, 0.5); // hinge around the left edge
    leftDoorView.center = CGPointMake(0.0, self.view.bounds.size.height/2.0); //compensate for anchor offset
    rightDoorView.layer.anchorPoint = CGPointMake(1.0, 0.5); // hinge around the right edge
    rightDoorView.center = CGPointMake(self.view.bounds.size.width,self.view.bounds.size.height/2.0); //compensate for anchor offset
}

- (IBAction)open
{
    CATransform3D transform = CATransform3DIdentity;
    transform.m34 = -1.0f/500;
    leftDoorView.layer.transform = transform;
    rightDoorView.layer.transform = transform;

    [UIView animateWithDuration:0.5 animations:^{

        leftDoorView.layer.transform = CATransform3DRotate(transform, M_PI_2, 0, 1, 0);
        rightDoorView.layer.transform = CATransform3DRotate(transform, -M_PI_2, 0, 1, 0);
    }];
}

- (IBAction)close
{
    [UIView animateWithDuration:0.5 animations:^{

        CATransform3D transform = CATransform3DIdentity;
        transform.m34 = -1.0f/500;
        leftDoorView.layer.transform = transform;
        rightDoorView.layer.transform = transform;
    }];
}