通过layoutIfNeeded()对特定的约束更改进行动画处理

时间:2019-04-20 03:31:14

标签: ios swift animation uiview uibutton

我已经以编程方式构造了视图,然后对其进行了动画处理。有一个视图动画链,最后一个是要动画的按钮。

当我通过调用layoutIfNeeded()来更改约束(这些约束独立于其他约束,并且没有其他视图与之相关)来使按钮动画化时,每件事都可以正常工作,但所有视图都会更改并转到动画的初始位置。

我什至尝试了一堆其他方法,例如更改alpha值等或使其消失。但是每一次,它都会改变整个视图。

现在,我无法找出确切原因。下面是它的代码。

是否有一种方法可以使用layoutIfNeeded()更改特定约束,或者使用其他任何方式来处理此功能?

import UIKit

var nextButton: UIButton!
var nextButtonHeightConstraint: NSLayoutConstraint?
var nextButtonWidthConstraint: NSLayoutConstraint?

override func viewDidLoad() {
    super.viewDidLoad()
    addNextButton()
}

// ..... function trigerred here.
@IBAction func triggerChange() {
    performCaptionAnimation()
}

func addNextButton() {
    nextButton = UIButton()
    nextButton.translatesAutoresizingMaskIntoConstraints = false
    nextButton.clipsToBounds = true
    nextButton.setTitle("Next", for: .normal)
    nextButton.backgroundColor = .white
    nextButton.isUserInteractionEnabled = true
    nextButton.titleLabel!.font = AvernirNext(weight: .Bold, size: 16)
    nextButton.setTitleColor(.darkGray, for: .normal)
    nextButton.roundAllCorners(withRadius: ActionButtonConstraint.height.anchor/2)
    nextButton.addGestureRecognizer(UITapGestureRecognizer(target: self, action: #selector(nextButtonPressed)))
    view.addSubview(nextButton)

    nextButtonHeightConstraint = nextButton.heightAnchor.constraint(equalToConstant: ActionButtonConstraint.height.anchor)
    nextButtonWidthConstraint = nextButton.widthAnchor.constraint(equalToConstant: ActionButtonConstraint.width.anchor)

    NSLayoutConstraint.activate([
        nextButton.rightAnchor.constraint(equalTo: view.rightAnchor, constant: ActionButtonConstraint.right.anchor),
        nextButton.bottomAnchor.constraint(equalTo: view.bottomAnchor, constant: ActionButtonConstraint.bottom.anchor),
        nextButtonHeightConstraint!, nextButtonWidthConstraint!
        ])
}

func performCaptionAnimation() {
    UIView.animate(withDuration: 0.4, delay: 0.0, options: [.curveEaseInOut], animations: {
        self.bannerTwoItemContainer.alpha = 1
        self.bannerTwoItemContainer.frame.origin.x -= (self.bannerTwoItemContainer.frame.width/2 + 10)
    }) { (done) in
        if done {
            UIView.animate(withDuration: 0.4, delay: 0.0, options: [.curveEaseInOut], animations: {
                self.bannerOneItemContainer.alpha = 1
                self.bannerOneItemContainer.frame.origin.x += self.bannerOneItemContainer.frame.width/2 + 10
            }) { (alldone) in
                if alldone {
                    // All changes here ......................
                    self.changeNextButtonContents()
                }
            }
        }
    }
}

// ------ This animation has issues and brings all the animation to it's initial point
func changeNextButtonContents() {
    self.nextButtonHeightConstraint?.constant = 40
    self.nextButtonWidthConstraint?.constant = 110
    UIView.animate(withDuration: 0.4, delay: 0.0, usingSpringWithDamping: 1, initialSpringVelocity: 1, options: [.curveEaseIn], animations: {
        self.nextButton.setTitleColor(.white, for: .normal)
        self.nextButton.setTitle("Try Now", for: .normal)
        self.nextButton.titleLabel?.font = AvernirNext(weight: .Bold, size: 18)
        self.nextButton.backgroundColor = blueColor
        self.nextButton.roundAllCorners(withRadius: 20)
        self.view.layoutIfNeeded()
    }, completion: nil)
}


1 个答案:

答案 0 :(得分:1)

问题在于,您的第一个动画会更改其视图的,就像self.bannerTwoItemContainer.frame.origin.x一样。但是您不能更改受约束定位的对象的框架。如果这样做,那么一旦布局发生,约束就会重新声明自己。那就是您正在做的事情,以及发生的事情。您说layoutIfNeeded,并且您从未更改的约束得到遵守。

重写第一个动画以更改其视图约束,而不是其帧约束,一切都会好起来。