ios - UIView 在变换动画之前具有自动布局约束 "jumps"

标签 ios autolayout ios-animations

我有一个受自动布局约束的 UIView。它居中并且有宽度和高度的约束。当它出现时,我正在对其应用旋转变换。

Rotated View

当我点击该动画按钮时,我希望它以动画方式移动到屏幕上更高的位置,同时旋转回“直立”位置(即不应用旋转)。因此,我设置了一个新的翻译转换:

let translation = CGAffineTransform(translationX: 1, y: -100)
UIView.animate(withDuration: 0.5, animations: {
   self.blueView.transform = translation
})

我期望看到的是 View 在向上平移时旋转回直立位置。

我得到的是 View “跳”到右侧的某个点,然后在旋转时向上动画。

如何解决这个问题,使其在动画之前不会“跳跃”?

enter image description here

最佳答案

您看到跳跃是因为当您设置平移变换动画时,blueView 已经设置了旋转变换。这会导致意想不到的结果。

要使其正常工作,您可以在动画之前组合旋转和平移变换,然后重置变换动画:

要将蓝色 View 平移向上 100pt 并将其旋转回正常状态,请执行以下操作:

  1. blueView 添加变换,将其向下平移 100pt 并旋转 45°
  2. 将 centerYAnchor 常量设置为 -100 以使 blueView 在动画之前处于正确的位置。
  3. blueView.transform = .identity 进行动画处理以删除变换动画

这是一个工作示例:

class ViewController: UIViewController {

    let blueView = UIView()

    override func viewDidLoad() {
        super.viewDidLoad()

        blueView.backgroundColor = .blue
        view.addSubview(blueView)

        blueView.transform = CGAffineTransform(translationX: 0, y: 100).rotated(by: -CGFloat.pi / 4)

        let button = UIButton(type: .custom)
        button.setTitle("Animate", for: .normal)
        button.setTitleColor(.blue, for: .normal)
        button.addTarget(self, action: #selector(didPress), for: .touchUpInside)
        view.addSubview(button)

        blueView.translatesAutoresizingMaskIntoConstraints = false
        button.translatesAutoresizingMaskIntoConstraints = false

        NSLayoutConstraint.activate([
            blueView.widthAnchor.constraint(equalToConstant: 20),
            blueView.heightAnchor.constraint(equalToConstant: 20),
            blueView.centerXAnchor.constraint(equalTo: view.centerXAnchor),
            blueView.centerYAnchor.constraint(equalTo: view.centerYAnchor, constant: -100),

            button.centerXAnchor.constraint(equalTo: view.centerXAnchor),
            button.bottomAnchor.constraint(equalTo: view.safeAreaLayoutGuide.bottomAnchor, constant: -40)
            ])
    }

    @objc func didPress(sender: UIButton) {
        UIView.animate(withDuration: 0.5, animations: {
            self.blueView.transform = .identity
        })
    }
}

关于ios - UIView 在变换动画之前具有自动布局约束 "jumps",我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47379953/

相关文章:

ios - 协议(protocol)功能的 Swift 选择器?

ios - 在我的 iPhone/在我的 iPad 文件夹上,如何为我的应用程序创建文件夹?

ios - 使用 Storyboard时如何在 IB 中为 UITableView 添加页脚 View ?

iPad Pro 的 iOS LaunchScreen 文件无法正常工作

ios - 修复 SwiftUI 表单中奇怪的 DatePicker 动画行为

ios - 如何在iOS中基于4个点绘制平滑形状?

ios - 以编程方式创建 UIButton 比使用 Storyboard 模糊

ios - 为什么当我相对于 super View 的底部进行约束时,它是从 super View 的顶部进行操作的?现在是这样吗?

ios - 插入带有大单元格的表格单元格动画

ios - 有没有办法改变动画速度?