在swift中转换动画错误?

时间:2014-10-03 02:24:37

标签: uiview swift core-animation transform calayer

这是目标c和swift的两个代码,两者都是相同的。 使用目标c它可以正确地缩放比例,但是在快速中它只是跳到最终值,我认为这是一个错误,有人可以测试并验证它吗?

目标C

    UIView *testView = [[UIView alloc] initWithFrame:CGRectMake(200, 200, 100, 100)];
    testView.backgroundColor = [UIColor greenColor];
    [self addSubview:testView];

    CAKeyframeAnimation * transformAnim = [CAKeyframeAnimation animationWithKeyPath:@"transform"];
    transformAnim.values                = @[[NSValue valueWithCATransform3D:CATransform3DMakeRotation(3 * M_PI/180, 0, 0, -1)],
                                            [NSValue valueWithCATransform3D:CATransform3DConcat(CATransform3DMakeScale(1.5, 1.5, 1), CATransform3DMakeRotation(3 * M_PI/180, 0, 0, 1))],
                                            [NSValue valueWithCATransform3D:CATransform3DMakeScale(1.5, 1.5, 1)],
                                            [NSValue valueWithCATransform3D:CATransform3DConcat(CATransform3DMakeScale(1.5, 1.5, 1), CATransform3DMakeRotation(-8 * M_PI/180, 0, 0, 1))]];
    transformAnim.keyTimes              = @[@0, @0.349, @0.618, @1];
    transformAnim.duration              = 1;
    [testView.layer addAnimation:transformAnim forKey:@"test"];

夫特

        let testView = UIView(frame: CGRectMake(200, 200, 100, 100))
        testView.backgroundColor = UIColor.greenColor()
        self.addSubview(testView)

        var transformAnim            = CAKeyframeAnimation(keyPath:"transform")
        transformAnim.values         = [NSValue(CATransform3D: CATransform3DMakeRotation(3 * CGFloat(M_PI/180), 0, 0, -1)),
            NSValue(CATransform3D: CATransform3DConcat(CATransform3DMakeScale(1.5, 1.5, 1), CATransform3DMakeRotation(3 * CGFloat(M_PI/180), 0, 0, 1))),
            NSValue(CATransform3D: CATransform3DMakeScale(1.5, 1.5, 1)),
            NSValue(CATransform3D: CATransform3DConcat(CATransform3DMakeScale(1.5, 1.5, 1), CATransform3DMakeRotation(-8 * CGFloat(M_PI/180), 0, 0, 1)))]
        transformAnim.keyTimes       = [0, 0.349, 0.618, 1]
        transformAnim.duration       = 1

        testView.layer.addAnimation(transformAnim, forKey: "transform")

这是objc anim,它按预期工作

objc transform anim 这是快速的动画,比例变换只是跳跃 swift transform anim

3 个答案:

答案 0 :(得分:5)

我在Objective-C和Swift中测试了你的代码,两种语言的行为完全相同(在两种情况下看起来都像你的第一个 gif动画)。

enter image description here

以下是如何确认我的结果。你的代码对我来说没有意义(添加一个视图并在一次动作中设置动画?)所以我将其分解为两个按钮方法,然后将其移动到视图控制器中。所以,这是在Objective-C:

@interface ViewController ()
@property (nonatomic) UIView* testView;
@end

@implementation ViewController
- (IBAction) doButton1 {
    UIView *testView = [[UIView alloc] initWithFrame:CGRectMake(200, 200, 100, 100)];
    testView.backgroundColor = [UIColor greenColor];
    [self.view addSubview:testView];
    self.testView = testView;
}
- (IBAction) doButton2 {
    CAKeyframeAnimation * transformAnim = [CAKeyframeAnimation animationWithKeyPath:@"transform"];
    transformAnim.values                = @[[NSValue valueWithCATransform3D:CATransform3DMakeRotation(3 * M_PI/180, 0, 0, -1)],
                                            [NSValue valueWithCATransform3D:CATransform3DConcat(CATransform3DMakeScale(1.5, 1.5, 1), CATransform3DMakeRotation(3 * M_PI/180, 0, 0, 1))],
                                            [NSValue valueWithCATransform3D:CATransform3DMakeScale(1.5, 1.5, 1)],
                                            [NSValue valueWithCATransform3D:CATransform3DConcat(CATransform3DMakeScale(1.5, 1.5, 1), CATransform3DMakeRotation(-8 * M_PI/180, 0, 0, 1))]];
    transformAnim.keyTimes              = @[@0, @0.349, @0.618, @1];
    transformAnim.duration              = 1;
    [self.testView.layer addAnimation:transformAnim forKey:@"test"];
}
@end

这里是Swift:

class ViewController: UIViewController {
    var testView : UIView!

    @IBAction func doButton1() {
        let testView = UIView(frame: CGRectMake(200, 200, 100, 100))
        testView.backgroundColor = UIColor.greenColor()
        self.view.addSubview(testView)
        self.testView = testView
    }
    @IBAction func doButton2() {
        var transformAnim            = CAKeyframeAnimation(keyPath:"transform")
        transformAnim.values         = [NSValue(CATransform3D: CATransform3DMakeRotation(3 * CGFloat(M_PI/180), 0, 0, -1)),
            NSValue(CATransform3D: CATransform3DConcat(CATransform3DMakeScale(1.5, 1.5, 1), CATransform3DMakeRotation(3 * CGFloat(M_PI/180), 0, 0, 1))),
            NSValue(CATransform3D: CATransform3DMakeScale(1.5, 1.5, 1)),
            NSValue(CATransform3D: CATransform3DConcat(CATransform3DMakeScale(1.5, 1.5, 1), CATransform3DMakeRotation(-8 * CGFloat(M_PI/180), 0, 0, 1)))]
        transformAnim.keyTimes       = [0, 0.349, 0.618, 1]
        transformAnim.duration       = 1
        self.testView.layer.addAnimation(transformAnim, forKey: "transform")
    }
}

现在,在任何一种语言中,点击第一个按钮(添加视图),然后点击第二个按钮(为其设置动画)。

答案 1 :(得分:2)

确保放

 self.targetView.layoutIfNeeded()

在调用动画之前。

 testView.layer.transform = CATransform3DConcat(CATransform3DMakeScale(1.5, 1.5, 1),      CATransform3DMakeRotation(-8 * CGFloat(M_PI/180), 0, 0, 1))
    testView.layer.addAnimation(transformAnim, forKey: "transform")

工作正常

答案 2 :(得分:0)

我对这个答案有点迟了,但我也注意到了这个错误。在Swift中,似乎您无法在动画制作之前立即添加子视图。好像你必须插入一个延迟,例如:

    let testView = UIView(frame: CGRectMake(200, 200, 100, 100))
    testView.backgroundColor = UIColor.greenColor()
    self.addSubview(testView)

    var timer = NSTimer.scheduledTimerWithTimeInterval(0.01, target: self, selector: "animate", userInfo: nil, repeats: false)
}

func animate() {
    var transformAnim            = CAKeyframeAnimation(keyPath:"transform")
    transformAnim.values         = [NSValue(CATransform3D: CATransform3DMakeRotation(3 * CGFloat(M_PI/180), 0, 0, -1)),
        NSValue(CATransform3D: CATransform3DConcat(CATransform3DMakeScale(1.5, 1.5, 1), CATransform3DMakeRotation(3 * CGFloat(M_PI/180), 0, 0, 1))),
        NSValue(CATransform3D: CATransform3DMakeScale(1.5, 1.5, 1)),
        NSValue(CATransform3D: CATransform3DConcat(CATransform3DMakeScale(1.5, 1.5, 1), CATransform3DMakeRotation(-8 * CGFloat(M_PI/180), 0, 0, 1)))]
    transformAnim.keyTimes       = [0, 0.349, 0.618, 1]
    transformAnim.duration       = 1

    testView.layer.addAnimation(transformAnim, forKey: "transform")
}