如何动画缩放和移动 UILabel,然后在完成后将其变换设置回身份并保留其框架?
How to animate scaling and moving a UILabel, then set its transform back to the identity when finished and preserve its frame?
我有一个 UILabel
正在尝试缩放和平移,我想制作动画。我通过在 UIView.animate
块中设置它的 transform
来做到这一点。动画完成后,我想将视图的 transform
设置回 .identity
并更新其框架,使其保持在 CGAffineTransform
移动它的位置。伪代码:
func animateMovement(label: UILabel,
newWidth: CGFloat,
newHeight: CGFloat,
newOriginX: CGFloat,
newOriginY: CGFloat)
{
UIView.animate(withDuration: duration, animations: {
label.transform = ??? // Something that moves it to the new location and new size
}) {
label.frame = ??? // The final frame from the above animation
label.transform = CGAffineTransform.identity
}
}
至于为什么我不简单地在动画块中分配新帧:我在标签内有文本,我想随动画缩放,这在动画更改帧而不是变换时是不可能的.
我遇到了坐标 space 问题,我可以看出这是因为在动画之后它不在正确的位置(标签的原点错误)。
这是我想出的答案。这将在动画持续时间内缩放内容,然后在完成时重置对象以进行恒等变换。
static func changeFrame(label: UILabel,
toOriginX newOriginX: CGFloat,
toOriginY newOriginY: CGFloat,
toWidth newWidth: CGFloat,
toHeight newHeight: CGFloat,
duration: TimeInterval)
{
let oldFrame = label.frame
let newFrame = CGRect(x: newOriginX, y: newOriginY, width: newWidth, height: newHeight)
let translation = CGAffineTransform(translationX: newFrame.midX - oldFrame.midX,
y: newFrame.midY - oldFrame.midY)
let scaling = CGAffineTransform(scaleX: newFrame.width / oldFrame.width,
y: newFrame.height / oldFrame.height)
let transform = scaling.concatenating(translation)
UIView.animate(withDuration: duration, animations: {
label.transform = transform
}) { _ in
label.transform = .identity
label.frame = newFrame
}
}
我有一个 UILabel
正在尝试缩放和平移,我想制作动画。我通过在 UIView.animate
块中设置它的 transform
来做到这一点。动画完成后,我想将视图的 transform
设置回 .identity
并更新其框架,使其保持在 CGAffineTransform
移动它的位置。伪代码:
func animateMovement(label: UILabel,
newWidth: CGFloat,
newHeight: CGFloat,
newOriginX: CGFloat,
newOriginY: CGFloat)
{
UIView.animate(withDuration: duration, animations: {
label.transform = ??? // Something that moves it to the new location and new size
}) {
label.frame = ??? // The final frame from the above animation
label.transform = CGAffineTransform.identity
}
}
至于为什么我不简单地在动画块中分配新帧:我在标签内有文本,我想随动画缩放,这在动画更改帧而不是变换时是不可能的.
我遇到了坐标 space 问题,我可以看出这是因为在动画之后它不在正确的位置(标签的原点错误)。
这是我想出的答案。这将在动画持续时间内缩放内容,然后在完成时重置对象以进行恒等变换。
static func changeFrame(label: UILabel,
toOriginX newOriginX: CGFloat,
toOriginY newOriginY: CGFloat,
toWidth newWidth: CGFloat,
toHeight newHeight: CGFloat,
duration: TimeInterval)
{
let oldFrame = label.frame
let newFrame = CGRect(x: newOriginX, y: newOriginY, width: newWidth, height: newHeight)
let translation = CGAffineTransform(translationX: newFrame.midX - oldFrame.midX,
y: newFrame.midY - oldFrame.midY)
let scaling = CGAffineTransform(scaleX: newFrame.width / oldFrame.width,
y: newFrame.height / oldFrame.height)
let transform = scaling.concatenating(translation)
UIView.animate(withDuration: duration, animations: {
label.transform = transform
}) { _ in
label.transform = .identity
label.frame = newFrame
}
}