Menganimasikan perubahan batasan tertentu dengan layoutIfNeeded()

Saya telah menyusun tampilan secara terprogram dan kemudian menganimasikannya. Terdapat animasi chain of view dan yang terakhir adalah tombol yang akan dianimasikan.

Sementara semuanya berfungsi dengan baik segera setelah saya menganimasikan tombol dengan mengubah batasan (batasan ini tidak tergantung pada yang lain dan tidak ada tampilan lain yang bergantung padanya) dengan memanggil layoutIfNeeded(), semua tampilan berubah dan menuju ke posisi awalnya dari animasi.

Saya bahkan mencoba banyak metode lain seperti mengubah nilai alpha dll atau menghilangkannya. tapi setiap saat, itu mengubah keseluruhan tampilan.

Sekarang, saya tidak dapat mengetahui penyebab pastinya. Di bawah ini adalah kodenya.

Apakah ada cara untuk mengubah batasan tertentu dengan layoutIfNeeded() atau cara lain untuk menangani fungsi ini?

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 sumber
comment
Anda tidak menganimasikan batasannya, tetapi membingkainya.   -  person Inder Kumar Rathore    schedule 20.04.2019
comment
@InderKumarRathore ???? Terima kasih sobat   -  person Aakash Dave    schedule 20.04.2019


Jawaban (1)


Masalahnya adalah animasi pertama Anda mengubah bingkai tampilannya, seperti pada self.bannerTwoItemContainer.frame.origin.x. Namun Anda tidak dapat mengubah bingkai dari sesuatu yang diposisikan berdasarkan batasan. Jika Anda melakukannya, maka segera setelah tata letak terjadi, kendala akan muncul kembali. Itulah tepatnya yang Anda lakukan dan itulah yang terjadi. Anda mengucapkan layoutIfNeeded dan batasan yang tidak pernah Anda ubah akan dipatuhi.

Tulis ulang animasi pertama Anda untuk mengubah batasan tampilannya, bukan bingkainya, dan semuanya akan baik-baik saja.

person matt    schedule 20.04.2019
comment
Saya suka mengatakan: kerangka dan batasan adalah musuh satu sama lain. Lebih teknisnya: batasan hanyalah daftar instruksi, dan tata letak berarti mematuhi instruksi tersebut. Dan bagaimana cara melakukannya? Dengan mengubah bingkai! - person matt; 20.04.2019
comment
Apa yang sebaiknya diutamakan secara umum. Batasan (menurut saya ini) atau bingkai, saat menggambar atau membuat animasi - person Aakash Dave; 20.04.2019
comment
Animasi bingkai boleh digunakan untuk animasi sementara, namun batasan pada akhirnya akan selalu menang. Jadi dalam hal ini jika penataan ulang ini hanya bersifat sementara, mungkin Anda bisa melakukan semuanya dengan bingkai; jika tidak, Anda perlu memikirkan cara melakukan segala sesuatu dengan batasan. - person matt; 20.04.2019
comment
Oke. Karena ini hanyalah animasi sementara, saya lebih suka menghilangkan batasan pada tombol itu sendiri daripada menambahkan batasan pada tampilan lain. - person Aakash Dave; 20.04.2019