Saya memiliki UIView yang ditempatkan di layar melalui beberapa kendala. Beberapa batasan dimiliki oleh superview, yang lainnya dimiliki oleh leluhur lain (misalnya, mungkin properti tampilan dari UIViewController).
Saya ingin menghapus semua batasan lama ini, dan menempatkannya di tempat baru menggunakan batasan baru.
Bagaimana saya bisa melakukan ini tanpa membuat IBOutlet untuk setiap batasan dan harus mengingat tampilan mana yang memiliki batasan tersebut?
Untuk menguraikan, pendekatan naif akan membuat sekelompok IBOutlet untuk setiap batasan, dan kemudian akan melibatkan kode panggilan seperti:
[viewA removeConstraint:self.myViewsLeftConstraint];
[viewB removeConstraint:self.myViewsTopConstraint];
[viewB removeConstraint:self.myViewsBottomConstraint];
[self.view removeConstraint:self.myViewsRightConstraint];
Masalah dengan kode ini adalah bahwa bahkan dalam kasus yang paling sederhana, saya perlu membuat 2 IBOutlets. Untuk tata letak yang kompleks, ini dapat dengan mudah mencapai 4 atau 8 IBOutlet yang diperlukan. Selain itu, saya perlu memastikan bahwa panggilan saya untuk menghapus batasan dipanggil pada tampilan yang tepat. Misalnya, bayangkan yang myViewsLeftConstraint
dimiliki olehviewA
. Jika saya tidak sengaja menelepon [self.view removeConstraint:self.myViewsLeftConstraint]
, tidak akan terjadi apa-apa.
Catatan: Metode constraintsAffectingLayoutForAxis terlihat menjanjikan, tetapi dimaksudkan untuk tujuan debug saja.
Update: Banyak jawaban saya menerima kesepakatan dengan self.constraints
, self.superview.constraints
atau beberapa varian dari mereka. Solusi ini tidak akan berfungsi karena metode tersebut hanya mengembalikan batasan yang dimiliki oleh tampilan, bukan yang memengaruhi tampilan.
Untuk memperjelas masalah dengan solusi ini, pertimbangkan hierarki tampilan ini:
- Kakek
- Ayah
- Saya
- Putra
- Putri
- Saudara
- Saya
- Paman
- Ayah
Sekarang bayangkan kita membuat batasan berikut, dan selalu melampirkannya ke leluhur terdekat yang terdekat:
- C0: Aku: sama dengan Anak (milik Aku)
- C1: Me: width = 100 (milik Me)
- C2: Aku: sama tingginya dengan Kakak (milik Ayah)
- C3: Saya: sama dengan Paman (milik Kakek)
- C4: Saya: kiri sama dengan Kakek (milik Kakek)
- C5: Kakak: kiri sama dengan Ayah (milik Ayah)
- C6: Paman: kiri sama dengan Kakek (milik Kakek)
- C7: Putra: kiri sama dengan Putri (milik Saya)
Sekarang bayangkan kita ingin menghapus semua kendala yang mempengaruhi Me
. Solusi yang tepat harus dihapus [C0,C1,C2,C3,C4]
dan tidak ada yang lain.
Jika Aku menggunakan self.constraints
(di mana diri adalah Aku), aku akan mendapatkannya [C0,C1,C7]
, karena hanya itu kendala yang dimiliki oleh-Ku. Jelas itu tidak akan cukup untuk menghapus ini karena hilang [C2,C3,C4]
. Selain itu, menghapus secara C7
tidak perlu.
Jika saya pakai self.superview.constraints
(di mana diri adalah Aku), saya akan dapatkan [C2,C5]
, karena itu adalah kendala yang dimiliki oleh Bapa. Jelas kami tidak dapat menghapus semua ini karena C5
sama sekali tidak terkait dengan Me
.
Jika saya menggunakan grandfather.constraints
, saya akan mendapatkan [C3,C4,C6]
. Sekali lagi, kami tidak dapat menghapus semua ini karena C6
harus tetap utuh.
Pendekatan kekerasan adalah untuk loop atas setiap nenek moyang pandangan (termasuk dirinya sendiri), dan melihat apakah firstItem
atau secondItem
adalah pandangan sendiri; jika demikian, hilangkan batasan itu. Ini akan mengarah pada solusi yang benar, kembali [C0,C1,C2,C3,C4]
, dan hanya kendala itu.
Namun, saya berharap ada solusi yang lebih elegan daripada harus menelusuri seluruh daftar leluhur.