Diperbarui untuk Swift 5
preferredLayoutAttributesFittingAttributes
diubah namanya menjadi preferredLayoutAttributesFitting
dan menggunakan ukuran otomatis
Diperbarui untuk Swift 4
systemLayoutSizeFittingSize
diganti namanya menjadi systemLayoutSizeFitting
Diperbarui untuk iOS 9
Setelah melihat solusi GitHub saya istirahat di iOS 9 saya akhirnya punya waktu untuk menyelidiki masalah ini sepenuhnya. Saya sekarang telah memperbarui repo untuk memasukkan beberapa contoh konfigurasi yang berbeda untuk sel-sel ukuran sendiri. Kesimpulan saya adalah bahwa sel-sel ukuran diri besar dalam teori tetapi berantakan dalam praktiknya. Sebuah kata peringatan ketika melanjutkan dengan sel sizing diri.
TL; DR
Lihat proyek GitHub saya
Sel ukuran sendiri hanya didukung dengan tata letak aliran jadi pastikan itulah yang Anda gunakan.
Ada dua hal yang Anda butuhkan untuk mengatur agar sel-sel ukuran sendiri berfungsi.
1. Set estimatedItemSize
diUICollectionViewFlowLayout
Tata letak aliran akan menjadi dinamis setelah Anda mengatur estimatedItemSize
properti.
self.flowLayout.estimatedItemSize = UICollectionViewFlowLayout.automaticSize
2. Tambahkan dukungan untuk ukuran pada subkelas sel Anda
Ini hadir dalam 2 rasa; Tata Letak Otomatis atau penggantian kustom preferredLayoutAttributesFittingAttributes
.
Buat dan konfigurasikan sel dengan Tata Letak Otomatis
Saya tidak akan masuk ke detail tentang ini karena ada posting SO brilian tentang mengkonfigurasi kendala untuk sel. Hanya berhati-hatilah bahwa Xcode 6 memecahkan banyak hal dengan iOS 7 jadi, jika Anda mendukung iOS 7, Anda harus melakukan hal-hal seperti memastikan autoresizingMask diatur pada konten sel. sel dimuat (yaitu awakeFromNib
).
Hal yang perlu Anda ketahui adalah bahwa sel Anda harus dibatasi lebih serius daripada Table View Cell. Misalnya, jika Anda ingin lebar Anda menjadi dinamis maka sel Anda membutuhkan batasan ketinggian. Demikian juga, jika Anda ingin ketinggian menjadi dinamis maka Anda akan memerlukan batasan lebar untuk sel Anda.
Terapkan preferredLayoutAttributesFittingAttributes
di sel khusus Anda
Ketika fungsi ini disebut, tampilan Anda telah dikonfigurasikan dengan konten (yaitu cellForItem
telah dipanggil). Dengan asumsi kendala Anda telah diatur dengan tepat, Anda dapat memiliki implementasi seperti ini:
//forces the system to do one layout pass
var isHeightCalculated: Bool = false
override func preferredLayoutAttributesFitting(_ layoutAttributes: UICollectionViewLayoutAttributes) -> UICollectionViewLayoutAttributes {
//Exhibit A - We need to cache our calculation to prevent a crash.
if !isHeightCalculated {
setNeedsLayout()
layoutIfNeeded()
let size = contentView.systemLayoutSizeFitting(layoutAttributes.size)
var newFrame = layoutAttributes.frame
newFrame.size.width = CGFloat(ceilf(Float(size.width)))
layoutAttributes.frame = newFrame
isHeightCalculated = true
}
return layoutAttributes
}
CATATAN Pada iOS 9 perilaku berubah sedikit yang dapat menyebabkan crash pada implementasi Anda jika Anda tidak hati-hati (Lihat lebih lanjut di sini ). Saat Anda menerapkan, preferredLayoutAttributesFittingAttributes
Anda perlu memastikan bahwa Anda hanya mengubah bingkai atribut tata letak Anda satu kali. Jika Anda tidak melakukan ini, tata letak akan memanggil implementasi Anda tanpa batas dan akhirnya macet. Salah satu solusinya adalah men-cache ukuran yang dihitung dalam sel Anda dan membatalkan ini kapan saja Anda menggunakan kembali sel atau mengubah kontennya seperti yang telah saya lakukan dengan isHeightCalculated
properti.
Rasakan tata letak Anda
Pada titik ini Anda harus memiliki sel dinamis 'berfungsi' di collectionView Anda. Saya belum menemukan solusi out-of-the-box yang cukup selama pengujian saya jadi jangan ragu untuk berkomentar jika Anda punya Rasanya masih seperti UITableView
memenangkan pertempuran untuk IMHO ukuran dinamis.
Peringatan
Perhatikan bahwa jika Anda menggunakan sel prototipe untuk menghitung estimasiItemSize - ini akan pecah jika XIB Anda menggunakan kelas ukuran . Alasannya adalah ketika Anda memuat sel Anda dari XIB, kelas ukurannya akan dikonfigurasikan Undefined
. Ini hanya akan rusak di iOS 8 dan lebih tinggi karena di iOS 7 kelas ukuran akan dimuat berdasarkan perangkat (iPad = Reguler-Any, iPhone = Compact-Any). Anda bisa mengatur Estimasi item tanpa memuat XIB, atau Anda dapat memuat sel dari XIB, menambahkannya ke collectionView (ini akan mengatur traitCollection), melakukan tata letak, dan kemudian menghapusnya dari superview. Atau Anda juga bisa membuat sel Anda menimpa traitCollection
pengambil dan mengembalikan sifat yang sesuai. Terserah kamu.
Beri tahu saya jika saya melewatkan sesuatu, semoga saya membantu dan semoga berhasil coding