Анимация конкретных изменений ограничений с помощью layoutIfNeeded()

Я программно создал представления, а затем анимировал их. Существует цепочка анимации просмотра, и последняя — это кнопка, которую нужно анимировать.

Хотя все работает нормально, как только я анимирую кнопку, изменяя ограничения (эти ограничения не зависят от других, и никакое другое представление не привязано к ним), вызывая layoutIfNeeded(), все представления изменяются и переходят в исходное положение анимации.

Я даже пробовал кучу других методов, таких как изменение альфа-значений и т. д. или его исчезновение. но каждый раз это меняет весь вид.

Сейчас точную причину установить не могу. Ниже приведен код этого.

Есть ли способ изменить только конкретное ограничение с помощью 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)
}



person Aakash Dave    schedule 20.04.2019    source источник
comment
вы анимируете не ограничения, а кадр.   -  person Inder Kumar Rathore    schedule 20.04.2019
comment
@InderKumarRathore ???? Спасибо, приятель   -  person Aakash Dave    schedule 20.04.2019


Ответы (1)


Проблема в том, что ваши первые анимации изменяют кадр своего представления, как в self.bannerTwoItemContainer.frame.origin.x. Но вы не можете изменить рамку того, что позиционируется с помощью ограничений. Если вы это сделаете, то, как только произойдет макет, ограничения снова заявят о себе. Это именно то, что вы делаете, и именно это происходит. Вы говорите layoutIfNeeded, и ограничения, которые вы никогда не меняли, соблюдаются.

Перепишите свои первые анимации, чтобы изменить ограничения их вида, а не кадра, и все будет хорошо.

person matt    schedule 20.04.2019
comment
Я люблю говорить: фрейм и ограничения — враги друг друга. С технической точки зрения: ограничения — это просто список инструкций, а компоновка означает выполнение этих инструкций. И как это сделать? Заменив рамку! - person matt; 20.04.2019
comment
Что вообще следует предпочесть. Ограничения (я так думаю) или рамки при рисовании или анимации - person Aakash Dave; 20.04.2019
comment
Кадровая анимация хороша для временной анимации, но в конечном итоге ограничения всегда побеждают. Итак, в этом случае, если эта перестановка носит временный характер, возможно, вы сможете все сделать с помощью фреймов; в противном случае вам нужно выяснить, как сделать все с ограничениями. - person matt; 20.04.2019
comment
Ok. Поскольку это всего лишь временная анимация, я скорее уберу ограничения для самой кнопки, чем добавлю ограничения для других представлений. - person Aakash Dave; 20.04.2019