Saya tahu bahwa rantai tata letak otomatis pada dasarnya terdiri dari 3 proses yang berbeda.
- memperbarui kendala
- tampilan tata letak (di sinilah kita mendapatkan perhitungan frame)
- tampilan
Yang tidak sepenuhnya jelas bagi saya adalah perbedaan batin antara -setNeedsLayout
dan -setNeedsUpdateConstraints
. Dari Apple Documents:
Panggil metode ini di utas utama aplikasi Anda ketika Anda ingin menyesuaikan tata letak subview tampilan. Metode ini mencatat permintaan dan segera kembali. Karena metode ini tidak memaksa pembaruan langsung, tetapi menunggu siklus pembaruan berikutnya, Anda dapat menggunakannya untuk membatalkan tata letak beberapa tampilan sebelum salah satu dari pandangan tersebut diperbarui. Perilaku ini memungkinkan Anda untuk menggabungkan semua pembaruan tata letak Anda ke satu siklus pembaruan, yang biasanya lebih baik untuk kinerja.
Ketika properti tampilan kustom Anda berubah dengan cara yang akan memengaruhi kendala, Anda dapat memanggil metode ini untuk menunjukkan bahwa kendala perlu diperbarui di beberapa titik di masa mendatang. Sistem kemudian akan memanggil updateConstraints sebagai bagian dari tata letak yang normal. Memperbarui kendala sekaligus sebelum mereka diperlukan memastikan bahwa Anda tidak perlu menghitung ulang kendala saat banyak perubahan dilakukan untuk tampilan Anda di antara lintasan tata letak.
Ketika saya ingin menghidupkan tampilan setelah memodifikasi batasan dan menghidupkan perubahan yang biasanya saya sebut misalnya:
[UIView animateWithDuration:1.0f delay:0.0f usingSpringWithDamping:0.5f initialSpringVelocity:1 options:UIViewAnimationOptionCurveEaseInOut animations:^{
[self.modifConstrView setNeedsUpdateConstraints];
[self.modifConstrView layoutIfNeeded];
} completion:NULL];
Saya mengetahui bahwa jika saya menggunakan -setNeedsLayout
alih-alih -setNeedsUpdateConstraints
semuanya berfungsi seperti yang diharapkan, tetapi jika saya ganti -layoutIfNeeded
dengan -updateConstraintsIfNeeded
, animasi tidak akan terjadi.
Saya sudah mencoba membuat kesimpulan sendiri:
-updateConstraintsIfNeeded
hanya memperbarui kendala tetapi tidak memaksa tata letak untuk masuk ke proses, sehingga bingkai asli masih dipertahankan-setNeedsLayout
panggilan juga-updateContraints
metode
Jadi kapan boleh menggunakan salah satu dari yang lain? dan tentang metode tata letak, apakah saya perlu memanggil mereka pada tampilan yang memiliki perubahan pada kendala atau pada tampilan induk?
Jawaban:
Kesimpulan Anda benar. Skema dasarnya adalah:
setNeedsUpdateConstraints
memastikan panggilan selanjutnya untukupdateConstraintsIfNeeded
panggilanupdateConstraints
.setNeedsLayout
memastikan panggilan selanjutnya untuklayoutIfNeeded
panggilanlayoutSubviews
.Ketika
layoutSubviews
dipanggil, ia juga memanggilupdateConstraintsIfNeeded
, jadi menelepon secara manual jarang diperlukan dalam pengalaman saya. Bahkan, saya belum pernah menyebutnya kecuali saat men-debug layout.Memperbarui batasan menggunakan
setNeedsUpdateConstraints
juga sangat jarang, objc.io – harus membaca tentang autolayout – mengatakan :Selain itu, dalam pengalaman saya, saya tidak pernah harus membatalkan batasan, dan tidak mengatur
setNeedsLayout
baris kode berikutnya, karena kendala baru cukup banyak meminta tata letak baru.Aturan praktisnya adalah:
setNeedsLayout
.updateConstraints
metode yang diganti (cara yang disarankan untuk mengubah kendala, btw), panggilsetNeedsUpdateConstraints
, dan sebagian besar waktu,setNeedsLayout
setelah itu.layoutIfNeeded
.Juga, dalam kode animasi Anda, saya percaya
setNeedsUpdateConstraints
tidak diperlukan, karena kendala diperbarui sebelum animasi secara manual, dan animasi hanya menampilkan ulang tampilan berdasarkan perbedaan antara yang lama dan yang baru.sumber
setNeedsLayout
.setNeedsLayout
memastikanlayoutSubviews
akan dipanggil dalam siklus pembaruan berikutnya, tetapi mungkin ini tidak ada hubungannya denganlayoutIfNeeded
?layoutSubviews
akan dipanggil secara otomatis, tidak perlu meneleponsetNeedsLayout
layoutSubviews
, jadi tidak perlu melakukannya secara manual. Namun, Anda harus meneleponlayoutIfNeeded
jika Anda ingin perubahan segera berlaku alih-alih siklus tata letak berikutnyaThe jawaban dengan coverback cukup benar. Namun, saya ingin menambahkan beberapa detail tambahan.
Di bawah ini adalah diagram dari siklus UIView khas yang menjelaskan perilaku lain:
-setNeedsLayout
alih-alih-setNeedsUpdateConstraints
semuanya berfungsi seperti yang diharapkan, tetapi jika saya ganti-layoutIfNeeded
dengan-updateConstraintsIfNeeded
, animasi tidak akan terjadi.updateConstraints
biasanya tidak melakukan apa pun. Itu hanya menyelesaikan kendala yang tidak berlaku sampailayoutSubviews
dipanggil. Jadi animasi memang membutuhkan panggilanlayoutSubviews
.Tidak, ini tidak perlu. Jika kendala Anda belum dimodifikasi, UIView akan mengabaikan panggilan
updateConstraints
. Anda perlu secara eksplisit meneleponsetNeedsUpdateConstraint
untuk memodifikasi kendala dalam proses.Untuk menelepon,
updateConstraints
Anda perlu melakukan yang berikut:sumber