【问题标题】:Animate specific constraint changes by layoutIfNeeded()通过 layoutIfNeeded() 对特定约束更改进行动画处理
【发布时间】:2019-09-10 04:56:48
【问题描述】:

我以编程方式构建了视图,然后为它们设置了动画。有一个视图动画链,最后一个是要动画的按钮。

当我通过调用 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)
}


【问题讨论】:

  • 您不是在为约束设置动画,而是为框架设置动画。
  • @InderKumarRathore ????谢谢老哥

标签: ios swift animation uiview uibutton


【解决方案1】:

问题是你的第一个动画改变了他们的视图的frame,就像self.bannerTwoItemContainer.frame.origin.x一样。但是你不能改变由约束定位的东西的框架。如果你这样做了,那么一旦布局发生,约束就会重新生效。这正是您正在做的事情以及发生的事情。你说layoutIfNeeded 并且你从未改变过的约束被遵守了。

重写您的第一个动画以更改其视图的约束,而不是它们的框架,一切都会好起来的。

【讨论】:

  • 我想说:框架和约束是天敌。从技术上讲:约束只是指令列表,布局意味着遵守这些指令。它是如何做到的?通过改变框架!
  • 一般应该首选什么。约束(我认为是这个)或框架,同时绘制或动画
  • 帧动画对于临时动画来说是可以的,但约束总是会最终获胜。所以在这种情况下,如果这种重新排列只是暂时的,也许你可以用框架来做任何事情;否则你需要弄清楚如何在约束条件下做所有事情。
  • 好的。由于这只是一个临时动画,我宁愿删除按钮本身的约束,而不是向其他视图添加约束。
猜你喜欢
  • 1970-01-01
  • 2019-08-31
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-11-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多