链接 UIView 动画与 CGAffineTransformscale 和翻译
Chaining UIView animation with CGAffineTransform scale & translate
我正在尝试使用 animate(withDuration:animations:)
为 Playground 中的 UIView 设置动画。目标是将视图向下移动,然后向右移动,同时按比例放大。
所以我分两步进行,在第一个动画完成后调用第二个动画。
这是我要应用到我的视图的 3 个转换
let scaleUp = CGAffineTransform(scaleX: 2, y: 2)
let moveDown = CGAffineTransform(translationX: 0, y: 100)
let moveRight = CGAffineTransform(translationX: 100, y: 0)
要做 moveDown
然后 moveRight
我将第二个连接到第一个。
UIView.animate(withDuration: 2, animations: {
circleView.transform = moveDown
}) { _ in
//First animation completed
UIView.animate(withDuration: 4, animations: {
circleView.transform = moveDown.concatenating(moveRight)
})
}
`
现在,当我试图在向右移动的同时放大视图时,它似乎正在将比例应用于已经转换的视图,这导致在第二个动画开始之前将所有内容向下移动(2 次)。
UIView.animate(withDuration: 2, animations: {
circleView.transform = moveDown
}) { _ in
//First animation completed
UIView.animate(withDuration: 2, animations: {
circleView.transform = moveDown.concatenating(scaleUp.concatenating(moveRight))
})
}
如何在不重置初始转换的情况下实现右移+放大?
在应用它们的变换顺序中,我认为是因为您在平移之前应用缩放,它采用按比例放大的值。
moveRight.concatenating(scaleUp)
可能工作正常。
我认为您的问题已经得到解答 in this post。据说,为了实现您的目标(两个同步动画),您需要使用 CAAnimationand 和 layer addAnimation
我试过了,效果很好
let scaleAA = CABasicAnimation(keyPath: "transform.scale")
scaleAA.fromValue = 1
scaleAA.byValue = 2
scaleAA.duration = 1
scaleAA.timingFunction = CAMediaTimingFunction.init(name: .easeOut)
let scaleXX = CABasicAnimation(keyPath: "position.x")
scaleXX.fromValue = 0
scaleXX.byValue = 20
scaleXX.duration = 1
scaleXX.timingFunction = CAMediaTimingFunction.init(name: .easeOut)
UIView.animate(withDuration: 1, animations: {
v1.transform = moveDown
}) { _ in
//First animation completed
v1.layer.add(scaleAA, forKey: "scale")
v1.layer.add(scaleXX, forKey: "xxxx")
}
我的解决方案更像是一个热修复程序,但它正是您想要的:
1
执行下移动画
2
恢复上面的转换(没有动画)
3
将 circleView
设置为下移变换后的位置(无动画)
4
执行向右移动和放大的动画
UIView.animate(withDuration: 2, animations: {
circleView.transform = moveDown //1
}) { _ in
//First animation completed
circleView.transform = .identity //2
circleView.frame.origin.y += 100 //3
UIView.animate(withDuration: 2, animations: {
circleView.transform = moveRight.concatenating(scaleUp) //4
})
}
我正在尝试使用 animate(withDuration:animations:)
为 Playground 中的 UIView 设置动画。目标是将视图向下移动,然后向右移动,同时按比例放大。
所以我分两步进行,在第一个动画完成后调用第二个动画。
这是我要应用到我的视图的 3 个转换
let scaleUp = CGAffineTransform(scaleX: 2, y: 2)
let moveDown = CGAffineTransform(translationX: 0, y: 100)
let moveRight = CGAffineTransform(translationX: 100, y: 0)
要做 moveDown
然后 moveRight
我将第二个连接到第一个。
UIView.animate(withDuration: 2, animations: {
circleView.transform = moveDown
}) { _ in
//First animation completed
UIView.animate(withDuration: 4, animations: {
circleView.transform = moveDown.concatenating(moveRight)
})
}
现在,当我试图在向右移动的同时放大视图时,它似乎正在将比例应用于已经转换的视图,这导致在第二个动画开始之前将所有内容向下移动(2 次)。
UIView.animate(withDuration: 2, animations: {
circleView.transform = moveDown
}) { _ in
//First animation completed
UIView.animate(withDuration: 2, animations: {
circleView.transform = moveDown.concatenating(scaleUp.concatenating(moveRight))
})
}
如何在不重置初始转换的情况下实现右移+放大?
在应用它们的变换顺序中,我认为是因为您在平移之前应用缩放,它采用按比例放大的值。
moveRight.concatenating(scaleUp)
可能工作正常。
我认为您的问题已经得到解答 in this post。据说,为了实现您的目标(两个同步动画),您需要使用 CAAnimationand 和 layer addAnimation
我试过了,效果很好
let scaleAA = CABasicAnimation(keyPath: "transform.scale")
scaleAA.fromValue = 1
scaleAA.byValue = 2
scaleAA.duration = 1
scaleAA.timingFunction = CAMediaTimingFunction.init(name: .easeOut)
let scaleXX = CABasicAnimation(keyPath: "position.x")
scaleXX.fromValue = 0
scaleXX.byValue = 20
scaleXX.duration = 1
scaleXX.timingFunction = CAMediaTimingFunction.init(name: .easeOut)
UIView.animate(withDuration: 1, animations: {
v1.transform = moveDown
}) { _ in
//First animation completed
v1.layer.add(scaleAA, forKey: "scale")
v1.layer.add(scaleXX, forKey: "xxxx")
}
我的解决方案更像是一个热修复程序,但它正是您想要的:
1
执行下移动画
2
恢复上面的转换(没有动画)
3
将 circleView
设置为下移变换后的位置(无动画)
4
执行向右移动和放大的动画
UIView.animate(withDuration: 2, animations: {
circleView.transform = moveDown //1
}) { _ in
//First animation completed
circleView.transform = .identity //2
circleView.frame.origin.y += 100 //3
UIView.animate(withDuration: 2, animations: {
circleView.transform = moveRight.concatenating(scaleUp) //4
})
}