Salah satu layar aplikasi kami mengharuskan kami untuk menempatkan bagian UICollectionView
dalam file UITableViewCell
. Ini UICollectionView
akan memiliki jumlah item yang dinamis, menghasilkan ketinggian yang juga harus dihitung secara dinamis. Namun, saya mengalami masalah saat mencoba menghitung ketinggian tertanam UICollectionView
.
Keseluruhan kami UIViewController
dibuat di Storyboards dan menggunakan tata letak otomatis. Tapi, saya tidak tahu bagaimana cara menaikkan ketinggian secara dinamis UITableViewCell
berdasarkan ketinggian UICollectionView
.
Adakah yang bisa memberikan beberapa tip atau saran tentang bagaimana mencapai ini?
ios
uitableview
uicollectionview
Manusia bayangan
sumber
sumber
UITableViewCell
berbeda dari tampilan tabel acutal-nya? Apakah Anda memerlukan pengguliran vertikal padaUICollectionView
danUITableView
Jawaban:
Jawaban yang benar adalah YA , Anda BISA melakukan ini.
Saya menemukan masalah ini beberapa minggu lalu. Ini sebenarnya lebih mudah dari yang Anda kira. Letakkan sel Anda di NIB (atau storyboard) dan sematkan agar tata letak otomatis melakukan semua pekerjaan
Diberikan struktur berikut:
Solusinya adalah memberi tahu tata letak otomatis untuk menghitung ukuran collectionViewCell terlebih dahulu, lalu tampilan koleksi contentSize, dan menggunakannya sebagai ukuran sel Anda. Ini adalah metode UIView yang "melakukan keajaiban":
Anda harus menyetel di sini ukuran TableViewCell, yang dalam kasus Anda adalah contentSize CollectionView.
CollectionViewCell
Pada CollectionViewCell Anda harus memberi tahu sel ke tata letak setiap kali Anda mengubah model (misalnya: Anda menyetel UILabel dengan teks, maka sel tersebut harus di tata letak lagi).
TableViewCell
The TableViewCell melakukan keajaiban. Ini memiliki outlet untuk CollectionView Anda, memungkinkan tata letak otomatis untuk sel CollectionView menggunakan estimatedItemSize dari UICollectionViewFlowLayout .
Kemudian, triknya adalah menyetel ukuran sel tableView Anda pada metode systemLayoutSizeFittingSize .... (CATATAN: iOS8 atau lebih baru)
CATATAN: Saya mencoba menggunakan metode ketinggian sel delegasi dari tableView.
-(CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
Tetapi sudah terlambat bagi sistem tata letak otomatis untuk menghitung CollectionView contentSize dan terkadang Anda mungkin menemukan sel yang diubah ukurannya salah.TableViewController
Ingatlah untuk mengaktifkan sistem tata letak otomatis untuk sel tableView di TableViewController Anda :
KREDIT: @rbarbera membantu menyelesaikan masalah ini
sumber
cell.bounds = CGRectMake(0, 0, CGRectGetWidth(tableView.bounds), 10000);
Ini akan "mensimulasikan" sel panjang dengan collectionView yang panjang, sehingga collectionView akan menghitung ukuran semua selnya. Jika tidak, collectionView hanya menghitung ukuran sel yang terlihat, dan salah menyetel tinggi talbeViewCell.systemLayoutSizeFittingSize
, saya mengalami masalah dengan cepat saat memuat ulang sel, aplikasi tampaknya macet setelahself.collectionView.layoutIfNeeded()
. Saya memperbaikinya dengan mengatur tinggi bingkai dengan 1 daripada tinggi maksimum. Semoga membantu jika ada yang tersandung dalam masalah ini.systemLayoutSizeFitting
, membalik urutan dari apa yang ditunjukkan dalam jawaban saat ini, jadi yang pertamacollectionView.layoutIfNeeded()
berjalan, lalucollectionView.frame = CGRect.init(origin: .zero, size: CGSize.init(width: targetSize.width, height: 1))
Saya pikir solusi saya jauh lebih sederhana daripada yang diusulkan oleh @PabloRomeu.
Langkah 1. Buat outlet dari
UICollectionView
keUITableViewCell subclass
, di manaUICollectionView
ditempatkan. Biarkan, namanya akancollectionView
Langkah 2. Tambahkan IB untuk
UICollectionView
batasan ketinggian dan buat jalan keluarUITableViewCell subclass
juga. Biarkan, namanya akancollectionViewHeight
.Langkah 3.
tableView:cellForRowAtIndexPath:
Tambahkan kode:sumber
collectionView
semua sisiUITableViewCell
dan settableView.estimatedRowHeight = 44;
dantableView.rowHeight = UITableViewAutomaticDimension;
Baik tampilan tabel maupun tampilan koleksi adalah
UIScrollView
subkelas dan karenanya tidak suka disematkan di dalam tampilan gulir lain saat mereka mencoba menghitung ukuran konten, menggunakan kembali sel, dll.Saya menyarankan Anda untuk menggunakan hanya tampilan koleksi untuk semua tujuan Anda.
Anda dapat membaginya menjadi beberapa bagian dan "memperlakukan" tata letak beberapa bagian sebagai tampilan tabel dan lainnya sebagai tampilan koleksi. Lagi pula, tidak ada yang tidak bisa Anda capai dengan tampilan koleksi yang Anda bisa dengan tampilan tabel.
Jika Anda memiliki tata letak kisi dasar untuk "bagian" tampilan koleksi, Anda juga dapat menggunakan sel tabel biasa untuk menanganinya. Namun jika Anda tidak memerlukan dukungan iOS 5, Anda harus menggunakan tampilan koleksi dengan lebih baik.
sumber
layoutAttributesForItemAtIndexPath
untuk bagian yang berbeda dalam subkelas khusus sayaUICollectionViewLayout
?Jawaban Pablo Romeu di atas ( https://stackoverflow.com/a/33364092/2704206 ) sangat membantu saya dengan masalah saya. Saya harus melakukan beberapa hal secara berbeda, bagaimanapun, agar ini bekerja untuk masalah saya. Pertama, saya tidak perlu
layoutIfNeeded()
sering menelepon . Saya hanya perlu memanggilnyacollectionView
di dalamsystemLayoutSizeFitting
fungsi.Kedua, saya memiliki batasan tata letak otomatis pada tampilan koleksi saya di sel tampilan tabel untuk memberikan beberapa padding. Jadi saya harus mengurangi margin depan dan belakang dari
targetSize.width
saat mengaturcollectionView.frame
lebar. Saya juga harus menambahkan margin atas dan bawah keCGSize
tinggi nilai pengembalian .Untuk mendapatkan konstanta pembatas ini, saya memiliki opsi untuk membuat outlet ke pembatas, meng-hard-coding konstanta mereka, atau mencarinya dengan pengenal. Saya memutuskan untuk menggunakan opsi ketiga untuk membuat kelas sel tampilan tabel kustom saya dengan mudah dapat digunakan kembali. Pada akhirnya, ini adalah semua yang saya butuhkan untuk membuatnya berfungsi:
Sebagai fungsi pembantu untuk mengambil batasan oleh pengenal, saya menambahkan ekstensi berikut:
CATATAN: Anda perlu menetapkan pengenal pada batasan ini di storyboard Anda, atau di mana pun batasan tersebut dibuat. Kecuali jika mereka memiliki konstanta 0, maka itu tidak masalah. Selain itu, seperti dalam tanggapan Pablo, Anda perlu menggunakan
UICollectionViewFlowLayout
tata letak untuk tampilan koleksi Anda. Terakhir, pastikan Anda menautkancollectionView
IBOutlet ke storyboard Anda.Dengan sel tampilan tabel kustom di atas, saya sekarang dapat membuat subkelasnya di sel tampilan tabel lain yang memerlukan tampilan koleksi dan menerapkan protokol
UICollectionViewDelegateFlowLayout
danUICollectionViewDataSource
. Semoga ini bisa membantu orang lain!sumber
Saya membaca semua jawaban. Ini sepertinya melayani semua kasus.
sumber
Alternatif untuk solusi Pablo Romeu adalah menyesuaikan UICollectionView itu sendiri, daripada melakukan pekerjaan dalam sel tampilan tabel.
Masalah yang mendasarinya adalah bahwa secara default tampilan koleksi tidak memiliki ukuran intrinsik sehingga tidak dapat menginformasikan tata letak otomatis dari dimensi yang akan digunakan. Anda bisa memperbaikinya dengan membuat subclass kustom yang mengembalikan ukuran intrinsik yang berguna.
Buat subclass UICollectionView dan ganti metode berikut
(Anda juga harus mengganti metode terkait: reloadSections, reloadItemsAtIndexPaths dengan cara yang mirip dengan reloadData ())
Memanggil layoutIfNeeded memaksa tampilan koleksi untuk menghitung ulang ukuran konten yang kemudian dapat digunakan sebagai ukuran intrinsik baru.
Selain itu, Anda perlu menangani perubahan ukuran tampilan secara eksplisit (misalnya pada rotasi perangkat) di pengontrol tampilan tabel
sumber
Saya menghadapi masalah yang sama baru-baru ini dan saya hampir mencoba setiap solusi dalam jawaban, beberapa di antaranya berhasil dan yang lainnya tidak menjadi perhatian utama saya tentang pendekatan @PabloRomeu adalah jika Anda memiliki konten lain di sel (selain tampilan koleksi) Anda harus menghitung tinggi dan tinggi batasannya dan mengembalikan hasilnya untuk mendapatkan tata letak otomatis yang benar dan saya tidak suka menghitung hal-hal secara manual dalam kode saya. Jadi, inilah solusi yang berfungsi dengan baik untuk saya tanpa melakukan perhitungan manual dalam kode saya.
dalam
cellForRow:atIndexPath
tampilan tabel saya melakukan hal berikut:Saya pikir apa yang terjadi di sini adalah saya memaksa sel tampilan tabel untuk menyesuaikan tingginya setelah ketinggian tampilan koleksi dihitung. (setelah memberikan tanggal collectionView ke sumber data)
sumber
Saya akan meletakkan metode statis pada kelas tampilan koleksi yang akan mengembalikan ukuran berdasarkan konten yang dimilikinya. Kemudian gunakan metode itu
heightForRowAtIndexPath
untuk mengembalikan ukuran yang sesuai.Perhatikan juga bahwa Anda bisa mendapatkan perilaku aneh saat menyematkan viewControllers semacam ini. Saya melakukannya sekali dan memiliki beberapa masalah ingatan aneh yang tidak pernah berhasil saya atasi.
sumber
Mungkin varian saya akan berguna; Saya telah memutuskan tugas ini selama dua jam terakhir. Saya tidak menganggap itu 100% benar atau optimal, tetapi keahlian saya masih sangat kecil dan saya ingin mendengar komentar dari para ahli. Terima kasih. Satu catatan penting: ini berfungsi untuk tabel statis - ini ditentukan oleh pekerjaan saya saat ini. Jadi, yang saya gunakan hanyalah viewWillLayoutSubviews dari tableView . Dan sedikit lagi.
sumber
Pendekatan termudah yang saya temukan, sejauh ini, Kredit untuk jawaban @igor di atas,
Di kelas tableviewcell Anda cukup masukkan ini
dan tentu saja, ubah collectionviewoutlet dengan outlet Anda di kelas sel
sumber
Saya mendapatkan ide dari postingan @Igor dan menginvestasikan waktu saya untuk proyek ini dengan cepat
Baru saja melewati ini di
Tambahan: Jika Anda melihat UICollectionView Anda berombak saat memuat sel.
sumber
Solusi Pablo tidak berfungsi dengan baik untuk saya, saya memiliki efek visual yang aneh (collectionView tidak menyesuaikan dengan benar).
Apa yang berhasil adalah menyesuaikan batasan tinggi collectionView (sebagai NSLayoutConstraint) ke collectionView contentSize selama
layoutSubviews()
. Ini adalah metode yang dipanggil saat autolayout diterapkan ke sel.sumber
Di UITableViewDelegate Anda:
Gantikan itemCount dan CollectionViewCellHeight dengan nilai sebenarnya. Jika Anda memiliki array itemCount array mungkin:
Atau terserah.
sumber
collectionViewCellHeight
sebelum dirender.1.Buat sel tiruan.
2. Gunakan metode collectionViewContentSize pada UICollectionViewLayout dari UICollectionView menggunakan data saat ini.
sumber
Anda dapat menghitung ketinggian koleksi berdasarkan sifat-sifatnya seperti
itemSize
,sectionInset
,minimumLineSpacing
,minimumInteritemSpacing
, jika AndacollectionViewCell
memiliki perbatasan aturan.sumber