在 Swift 中设置动画之前如何对 UILabel 应用变换?
How do you apply a transform to a UILabel before animating in Swift?
我希望在视图为比例设置动画之前先旋转视图而不设置动画。如果我之后有动画,我现在拥有它的方式会忽略我的初始视图旋转。
label.transform = CGAffineTransform(rotationAngle: CGFloat(90.0 * .pi / 180))
animateLabel(label:label)
func animateLabel(label:UILabel) {
label.transform = CGAffineTransform(scaleX: 0.6, y: 0.6)
UIView.animate(withDuration: 0.2, animations: {
label.transform = CGAffineTransform(scaleX: 1.1, y: 1.1)
},
completion: { _ in
UIView.animate(withDuration: 0.1) {
label.transform = CGAffineTransform(scaleX: 1.0, y: 1.0)
}
})
}
更新:我如何使用 Matt 的回答更新我的代码以使其正确动画:
我首先将初始旋转设置为变换变量,然后在调用 animateLabel 时发送它:
var transforms: CGAffineTransform = .identity
transforms = transforms.concatenating(CGAffineTransform(rotationAngle: CGFloat(90.0 * .pi / 180)))
animateLabel(label:label, transforms:transforms)
我连接比例并将变换设置为修改后的变换。然后我可以对实际动画使用缩放比例:
func animateLabel(label:UILabel, transforms:CGAffineTransform) {
transforms.concatenating(CGAffineTransform(scaleX: 0.6, y: 0.6))
label.transform = transforms
UIView.animate(withDuration: 0.2, animations: {
label.transform = transforms.scaledBy(x: 1.1, y: 1.1)
},
completion: { _ in
UIView.animate(withDuration: 0.1) {
label.transform = transforms.scaledBy(x: 1.0, y: 1.0)
}
})
}
The way I have it now ignores my initial view rotation if I have the animation afterwards.
很容易看出原因。一个视图只有一个转换。您的第二个转换 替换 第一个:
label.transform = CGAffineTransform(rotationAngle: CGFloat(90.0 * .pi / 180))
label.transform = CGAffineTransform(scaleX: 0.6, y: 0.6)
这就是你正在做的。相反,您需要 apply 第二个转换 to 第一个。查看将第二个转换与第一个转换相结合的方法,而不是完全替换第一个转换。例如https://developer.apple.com/documentation/coregraphics/cgaffinetransform/1455882-scaledby
因此我很容易得到这个,这似乎是你想要的粗略近似值:
为此,我准备了两个变换,即旋转和旋转加缩放:
let rot = CGAffineTransform(rotationAngle: CGFloat(90.0 * .pi / 180))
let scale = rot.scaledBy(x: 1.5, y: 1.5)
我希望在视图为比例设置动画之前先旋转视图而不设置动画。如果我之后有动画,我现在拥有它的方式会忽略我的初始视图旋转。
label.transform = CGAffineTransform(rotationAngle: CGFloat(90.0 * .pi / 180))
animateLabel(label:label)
func animateLabel(label:UILabel) {
label.transform = CGAffineTransform(scaleX: 0.6, y: 0.6)
UIView.animate(withDuration: 0.2, animations: {
label.transform = CGAffineTransform(scaleX: 1.1, y: 1.1)
},
completion: { _ in
UIView.animate(withDuration: 0.1) {
label.transform = CGAffineTransform(scaleX: 1.0, y: 1.0)
}
})
}
更新:我如何使用 Matt 的回答更新我的代码以使其正确动画:
我首先将初始旋转设置为变换变量,然后在调用 animateLabel 时发送它:
var transforms: CGAffineTransform = .identity
transforms = transforms.concatenating(CGAffineTransform(rotationAngle: CGFloat(90.0 * .pi / 180)))
animateLabel(label:label, transforms:transforms)
我连接比例并将变换设置为修改后的变换。然后我可以对实际动画使用缩放比例:
func animateLabel(label:UILabel, transforms:CGAffineTransform) {
transforms.concatenating(CGAffineTransform(scaleX: 0.6, y: 0.6))
label.transform = transforms
UIView.animate(withDuration: 0.2, animations: {
label.transform = transforms.scaledBy(x: 1.1, y: 1.1)
},
completion: { _ in
UIView.animate(withDuration: 0.1) {
label.transform = transforms.scaledBy(x: 1.0, y: 1.0)
}
})
}
The way I have it now ignores my initial view rotation if I have the animation afterwards.
很容易看出原因。一个视图只有一个转换。您的第二个转换 替换 第一个:
label.transform = CGAffineTransform(rotationAngle: CGFloat(90.0 * .pi / 180))
label.transform = CGAffineTransform(scaleX: 0.6, y: 0.6)
这就是你正在做的。相反,您需要 apply 第二个转换 to 第一个。查看将第二个转换与第一个转换相结合的方法,而不是完全替换第一个转换。例如https://developer.apple.com/documentation/coregraphics/cgaffinetransform/1455882-scaledby
因此我很容易得到这个,这似乎是你想要的粗略近似值:
为此,我准备了两个变换,即旋转和旋转加缩放:
let rot = CGAffineTransform(rotationAngle: CGFloat(90.0 * .pi / 180))
let scale = rot.scaledBy(x: 1.5, y: 1.5)