UIView 在使用约束缩放后动画到错误的位置

UIView animating to wrong position after being scaled while using constraints

所以我正在尝试制作一个 UILabel 的动画以匹配另一个 UILabel 大小和位置。起初我只使用这样的约束来处理位置部分的动画:

private lazy var constraintsForStateA: [NSLayoutConstraint] = [
    firstLabel.leadingAnchor.constraint(equalTo: view.leadingAnchor, constant: 10),
    firstLabel.centerYAnchor.constraint(equalTo: view.centerYAnchor)
]


private lazy var constraintsForStateB: [NSLayoutConstraint] = [
    firstLabel.leadingAnchor.constraint(equalTo: secondLabel.leadingAnchor),
    firstLabel.topAnchor.constraint(equalTo: secondLabel.topAnchor)
]

所以我基本上有两个具有上述约束的数组(constraintsForStateAconstraintsForStateB),当我需要为我的 firstLabel 的位置设置动画时,我只需要执行如下操作:

// From state A to state B
UIView.animate(withDuration: 0.2, delay: 0, options: .curveEaseOut) {
        NSLayoutConstraint.deactivate(self._constraintsUnselected)
        NSLayoutConstraint.activate(self._constraintsSelected)
        self.layoutIfNeeded()
    } completion: { _ in
        self.firstLabel.alpha = 0
        self.secondLabel.alpha = 1
    }
}

到目前为止,这完全符合我的预期,但是大小部分给我带来了一些麻烦,因为我不能对文本大小应用相同的策略我正在使用这样的转换:

let scaleX = secondLabel.bounds.width / firstLabel.bounds.width
let scaleY = secondLabel.bounds.height / firstLabel.bounds.height

然后在上面相同的 .animate 方法中从状态 A 到状态 B 我这样做:

firstLabel.transform = CGAffineTransform(scaleX: scaleX, y: scaleY)

从B状态到A状态:

firstLabel.transform = .identity

按我的意愿工作,但我面临的问题是该位置不再位于预期位置。我认为发生这种情况是因为考虑到标签中心的 anchorPoint ,正在发生转换。我尝试过将 anchorPoint 更改为 (0,0),但它也不起作用。我已经为此浪费了 2 天时间,欢迎任何帮助或指导!

当你做动画的时候,如果你忘记约束而只处理帧会简单得多:

NSLayoutConstraint.deactivate(self.constraintsForStateA)
firstLabel.translatesAutoresizingMaskIntoConstraints = true
UIView.animate(withDuration: 0.2, delay: 0, options: .curveEaseOut) {
    firstLabel.frame = secondLabel.frame
}

然后从状态B转换到A:

firstLabel.translatesAutoresizingMaskIntoConstraints = false
UIView.animate(withDuration: 0.2, delay: 0, options: .curveEaseOut) {
    NSLayoutConstraint.activate(self.constraintsForStateA)
    self.layoutIfNeeded()
}