约束动画只会向上移动,不会向下移动

时间:2018-02-22 23:19:46

标签: ios swift animation autolayout

我有两个按钮可以触发两个对象上的动画 - 一个视图和一个imageView - 其定位由自动布局设置。 (在尝试解决问题时,我将目的地简化为屏幕的顶部和底部。):

@objc func upButtonTapped() {
    self.logo.centerYAnchor.constraint(equalTo: self.view.topAnchor, constant: 0).isActive = true
    self.inputsView.bottomAnchor.constraint(equalTo: self.view.topAnchor, constant: 0).isActive = true
    UIView.animate(withDuration: 0.3) {
        self.view.layoutIfNeeded()
    }
    print("Up")
}
@objc func downButtonTapped() {
    self.logo.centerYAnchor.constraint(equalTo: self.view.bottomAnchor, constant: 0).isActive = true
    self.inputsView.bottomAnchor.constraint(equalTo: self.view.bottomAnchor, constant: 0).isActive = true
    UIView.animate(withDuration: 0.3) {
        self.view.layoutIfNeeded()
    }
    print("Down")
}

upButtonTapped动画工作正常,但downButtonTapped却没有。在玩了很长时间的目的地之后,我意识到没有锚点和约束的组合将导致对象在屏幕上制作动画。这两个函数都是由各自的按钮正确定位的,我尝试将每个函数之间的约束更新交换为相同的结果。

如果它有帮助,这是我为两个对象设置的初始约束(使用自定义扩展):

logo.anchor(xCenter: view.centerXAnchor,
            yCenter: view.topAnchor, yCenterConstant: view.frame.height / 3,
            width: 65)
inputsView.anchor(bottom: view.safeAreaLayoutGuide.bottomAnchor, bottomConstant: -100,
                  xCenter: view.centerXAnchor,
                  width: view.frame.width * 0.7,
                  height: 200)

任何人都可以告诉我发生了什么/如何修复?

2 个答案:

答案 0 :(得分:0)

我用一个视图复制了你的结果。您的问题是您的视图过度受限,因为您不断添加新约束,但您永远不会删除它们。当视图过度约束时,自动布局会通过选择要忽略的约束来打破约束。无论出于何种原因,它都有利于" up"限制。您需要拥有一个跟踪垂直约束的属性,并且需要在创建和激活新约束之前在该约束上设置isActive = false

以下是我的示例代码。我正在将一个红色方块视图移动到屏幕的顶部和底部。请注意我如何使用属性来跟踪在垂直方向上定位视图的约束以及如何使用该属性来停用当前约束,然后存储并激活新约束。

class ViewController: UIViewController {

    @IBOutlet weak var redView: UIView!

    @IBOutlet weak var redCenter: NSLayoutConstraint!

    var redCenterConstraint: NSLayoutConstraint?

    override func viewDidLoad() {
        super.viewDidLoad()

        // start with the constraint set in the Storyboard
        redCenterConstraint = redCenter
    }

    @IBAction func moveUp(_ sender: UIButton) {
        // deactivate the current constraint
        redCenterConstraint?.isActive = false

        // create the new constraint
        redCenterConstraint = redView.centerYAnchor.constraint(equalTo: self.view.topAnchor, constant: 0)

        // activate the new constraint
        redCenterConstraint?.isActive = true

        // animate the change
        UIView.animate(withDuration: 0.3) {
            self.view.layoutIfNeeded()
        }
    }

    @IBAction func moveDown(_ sender: UIButton) {
        // deactivate the current constraint
        redCenterConstraint?.isActive = false

        // create the new constraint
        redCenterConstraint = redView.centerYAnchor.constraint(equalTo: self.view.bottomAnchor, constant: 0)

        // activate the new constraint
        redCenterConstraint?.isActive = true

        // animate the change
        UIView.animate(withDuration: 0.3) {
            self.view.layoutIfNeeded()
        }
    }
}

这是在模拟器中运行的:

enter image description here

答案 1 :(得分:0)

尝试以下代码我只需添加完成处理程序:---

func downAnimation() {
    UIView.animate(withDuration: 1.4, delay: 0.0, options: [],animations: {
        self.logo.centerYAnchor.constraint(equalTo: self.view.bottomAnchor, constant: 0).isActive = true
        self.inputsView.bottomAnchor.constraint(equalTo:    self.view.bottomAnchor, constant: 0).isActive = true
    }) { (complete) in

        if self.isAnimate{
            self.upAnimation()
        }
    }
}

func upAnimation() {
    UIView.animate(withDuration: 1.4, delay: 0.0, options: [],animations: {
        self.logo.centerYAnchor.constraint(equalTo: self.view.topAnchor, constant: 0).isActive = true
        self.inputsView.bottomAnchor.constraint(equalTo: self.view.topAnchor, constant: 0).isActive = true
    }) { (complete) in
        if self.isAnimate {
            self.downAnimation()
        }
    }
}

希望它能帮到你, 谢谢。