【问题标题】:Transform animation bug in swift?快速转换动画错误?
【发布时间】:2014-10-03 02:24:37
【问题描述】:

这里是objective c 和swift 的两个代码,都是一样的。 使用objective 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 动画,它按预期工作

这是快速动画,缩放变换只是跳跃

【问题讨论】:

  • 动画应该做什么?我想确保我玩的东西朝着正确的方向发展。
  • @MinnesotaSteve 它应该为视图设置动画,并为旋转设置动画。使用 objc 可以正常工作,但旋转动画效果很好,但它只是跳转到最终比例而没有动画
  • 好的,+1 制作漂亮的 gif 动画来说明问题! :)
  • 您是否有任何此项目中可能会影响此的其他代码?尝试测试 only 代码是我提供的代码。
  • 根据给出的信息无法重现。在此基础上投票结束问题。

标签: uiview swift core-animation transform calayer


【解决方案1】:

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

这是确认我的结果的方法。你的代码对我来说没有意义(添加一个视图并一次完成所有动画?)所以我把它分成两个按钮方法,然后我把它移到视图控制器中。所以,它在 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")
    }
}

现在,无论哪种语言,点击第一个按钮(添加视图),然后点击第二个按钮(动画)。

【讨论】:

  • 我已经用 gif 图片更新了我的问题,我已经复制了你的 Swift 代码,但是规模仍然在跳跃,我想知道这是什么问题?
  • 在我的测试中,它会在动画完成时 在结尾处 跳转,但这是非常合理的,而且它在两种语言中都可以做到。
  • 你在什么系统上测试? iOS 7 还是 iOS 8?
  • 从头开始 - 我尝试了 iOS 7 和 iOS 8,两者都很流畅。
  • 我在 iOS 8 上测试过,我认为 swift 只适用于 iOS 8 不是吗。你使用什么 Xcode 版本?我正在使用 Xcode 6.0 版本
【解决方案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")

效果很好

【讨论】:

  • 在 viewDidAppear 上吗?
  • 好的,我知道了。在调用动画之前,只需将最新值放在列表中
  • 这就是我之前所做的,layoutIfNeeded() 在开始动画之前。不,它不在 viewDidAppear 中。
  • 1) 你想放在那里 2) 在调用动画之前,将最后一个变换值设置为你的图层,我检查过,它作为例外工作并且不会跳转。请检查更新。
【解决方案3】:

这个答案我有点晚了,但我也注意到了这个错误。在 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")
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2015-10-07
    • 2021-01-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多