CellForItemAtIndexPath UICollectionView tidak dipanggil

104

Hanya kedua kalinya saya menggunakan UICollectionView dan mungkin saya telah menggigit lebih dari yang bisa saya kunyah tetapi bagaimanapun:

Saya mengimplementasikan UICollectionView (myCollectionView) yang menggunakan UICollectionViewCell kustom yang telah saya subkelas. Sel subclass (FullReceiptCell) berisi UITableView dan merupakan ukuran viewcontroller. Saya mencoba untuk memungkinkan pengguliran horizontal antara FullReceiptCells.

UICollectionViewController subclass yang berisi myCollectionView sedang didorong ke tumpukan pengontrol nav. Saat ini, loas myCollectionView dan pengguliran horizontal diaktifkan. Namun, tidak ada sel yang terlihat. Saya sudah konfirmasi itu

- (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section

telah berjalan dan mengembalikan integer yang lebih besar dari 0. Saya juga telah mengonfirmasi bahwa delegasi dan sumber data myCollectionView disetel dengan benar di IB ke UICollectionViewController subclass.

Metode di mana sel akan dimuat:

- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath

tidak dipanggil.

Di sinilah saya mendorong UICollectionViewController dan metode viewDidLoad saya di dalam pengontrol itu (CATATAN: initWithBill adalah menimpa penginisialisasi normal):

Di file ViewControllers .m sebelumnya:

FullReceiptViewController *test = [[FullReceiptViewController alloc] initWithBill:currentBill];
test.title = @"Review";
[self.navigationController pushViewController:test animated:YES];

Di FullReceiptViewController.m:

- (void)viewDidLoad
{
    [super viewDidLoad];
    // Do any additional setup after loading the view from its nib.
    [self.myCollectionView registerClass:[FullReceiptCell class] forCellWithReuseIdentifier:@"FullReceiptCellIdentifier"];
    self.myCollectionView.pagingEnabled = YES;
    // Setup flowlayout

    self.myCollectionViewFlowLayout = [[UICollectionViewFlowLayout alloc] init];
    [self.myCollectionViewFlowLayout setItemSize:CGSizeMake(320, 548)];
    [self.myCollectionViewFlowLayout setSectionInset:UIEdgeInsetsMake(0, 0, 0, 0)];
    [self.myCollectionViewFlowLayout setScrollDirection:UICollectionViewScrollDirectionHorizontal];
    self.myCollectionViewFlowLayout.minimumLineSpacing = 0;
    self.myCollectionViewFlowLayout.minimumInteritemSpacing = 0;
    [self.myCollectionView setCollectionViewLayout:myCollectionViewFlowLayout];
    //testing to see if the collection view is loading
    self.myCollectionView.backgroundColor = [UIColor colorWithWhite:0.25f alpha:1.0f];

Ada petunjuk mengapa tidak dipanggil?

IkegawaTaro
sumber
Saya menggunakan XIB. Saya tidak bisa membatalkan apa pun di cellForItemsAtIndexPath karena tidak pernah dipanggil.
IkegawaTaro

Jawaban:

135

Bagi yang tersandung disini nanti .... alasannya:

- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath

tidak dipanggil karena tinggi itemSize untuk collectionViewFlowLayout terlalu besar.

[self.myCollectionViewFlowLayout setItemSize:CGSizeMake(320, 548)];

Jika saya mengubah tinggi menjadi 410, itu akan mengeksekusi cellForItemAtIndexPath.

IkegawaTaro
sumber
Bisakah Anda menjelaskan lebih lanjut. Hal yang sama terjadi pada saya
user1010819
Saya baru saja menemukan bahwa Anda juga perlu berhati-hati dengan collectionViewContentSize
Dimitar Marinov
49
Jika Anda menggunakan autolayout - pastikan untuk menyetel batasan ketinggian pada collectionView - menghabiskan banyak waktu untuk hal ini!
bpn
untuk batasan ketinggian rekor tidak berhasil bagi saya .. Batasan tengah horizontal berhasil
Mohamed Emad Hegab
4
Jika collectionView Anda dibatasi ke topLayoutGuide dengan AutoLayout, dan tidak seharusnya di-scroll di bawah NavigationBar, pastikan untuk menghapus centang Adjust Scroll View Insetsdi ViewController Anda di Storyboard.
Bruno Galinari
96

Dalam kasus saya, itu karena kelas tata letak saya salah disubkelas dari, UICollectionViewLayoutbukanUICollectionViewFlowLayout

esilver
sumber
1
TERIMA KASIH. Bugger saya, saya menghabiskan waktu lama untuk itu.
Rambatino
Ini juga masalah saya! Ini sedikit berlawanan dengan intuisi, jadi itu bahkan tidak terpikir oleh saya. Terima kasih untuk ini!
WendiKidd
Sama untuk ku! sangat mudah untuk mengabaikannya! terima kasih lagi
arvidur
Telapak tangan di sini, terima kasih telah menunjukkan hal ini (4 tahun yang lalu).
Milander
Saya menghadapi masalah yang sama. Terima kasih
Piyush Gupta
31

CellForItemAtIndexPath tidak akan dipanggil jika Anda tidak memberikan informasi ukuran konten ke tampilan koleksi.

  1. Jika Anda menggunakan tata letak Flow : Anda perlu mengatur ukuran item dengan benar.
  2. Jika Anda memiliki tata letak khusus yang disubkelas dari UICollectionViewLayout : Pastikan Anda mengembalikan ukuran yang sesuai dari metode collectionViewContentSize.

Dalam kasus yang terakhir, Anda juga akan mengamati bahwa layoutAttributesForElementsRect Anda juga tidak dipanggil. Alasannya adalah Anda belum menentukan berapa ukuran konten Anda dan secara default ukurannya adalah CGSizeZero. Ini pada dasarnya memberi tahu tampilan koleksi bahwa Anda tidak memiliki konten apa pun untuk dilukis sehingga tidak repot menanyakan atribut atau sel kepada Anda.

Jadi, cukup timpa collectionViewContentSize dan berikan ukuran yang sesuai di sana, itu akan menyelesaikan masalah Anda.

Deepak GM
sumber
1
Misalnya untuk menggunakan ukuran penuh yang tersedia, kembalikan collectionView.frame.size dari collectionViewContentSize (bukan hanya collectionView.contentSize yang defaultnya ke 0, 0)
Adam Loving
Terima kasih! Jawaban ini membantu saya b / c Saya memiliki UICollectionViewLayout kustom. Jika saya memulai aplikasi dalam simulator dalam orientasi lanskap, beberapa sel tidak muncul di tampilan awal. Mengganti ukuran konten memperbaiki masalah ini untuk saya.
Chris Livdahl
1
Terima kasih. Dalam kasus saya, collectionViewContentSizesalah mengembalikan 0 untuk lebarnya, itulah mengapa cellForItemAtIndexPathtidak dipanggil.
izerik
16

Mungkin saya hanya mengabaikannya, tetapi tampaknya delegasi dan sumber data Anda hilang. Di file header Anda, pastikan Anda telah menambahkan ini:

<UICollectionViewDelegate, UICollectionViewDataSource>

dan dalam metode viewDidLoad Anda, tambahkan ini:

self.myCollectionView.delegate = self;
self.myCollectionView.dataSource = self;

Selain itu, jika Anda memuatnya melalui .xib, pastikan Anda telah menghubungkan IBOutlet ke UICollectionView.

Anthony Castelli
sumber
1
Saya tidak menunjukkannya tetapi saya sudah mencatat delegasi dan sumber data di file header. Selain itu, saya telah menghubungkan IBOutlet ke myCollectionView. Delegasi dan sumber data untuk collectionview ini telah disetel ke FullReceiptViewController. Yang aneh adalah numberOfItemsInSection (metode protokol sumber data) dipanggil dan mengembalikan integer yang lebih besar dari 0.
IkegawaTaro
Hmm, Saat Anda meluncurkan aplikasi, apakah tampilan Koleksi menunjukkan atau melakukan sesuatu? Sepertinya ada beberapa item di dalamnya jika numberOfItemsInSection mengembalikan sesuatu yang lebih besar dari 0.
Anthony Castelli
Terima kasih telah menindaklanjuti. Tampilan koleksi memang menunjukkan ... Saya tahu karena saya mengubah warna latar belakang. Saya yakin saya telah menemukan masalahnya: [self.myCollectionViewFlowLayout setItemSize: CGSizeMake (320, 548)]; Ini terlalu besar. Jika saya menurunkan tinggi menjadi 410, saya bisa memanggil metode cellForItemAtIndexPath.
IkegawaTaro
@AnthonyCastelli Halo, Saya juga menghadapi masalah yang sama, numberOfItemsInSection dipanggil pada pop ke viewController tetapi tidak cellForItemsAtIndexPath. jadi, apakah kamu mendapatkan petunjuk?
Bhavin Kansagara
16

Untuk hierachy tampilan yang lebih rumit, silakan periksa blog ini . Itu menyelamatkan hidup saya!

self.automaticallyAdjustsScrollViewInsets = NO;
Jaybo
sumber
1
Saya menghabiskan begitu banyak waktu untuk ini - dan semuanya bermuara pada itu. Jika menggunakan storyboard atau XIB, lihat pengontrol tampilan induk dan batal pilih "Sesuaikan Insets Tampilan Scroll" di Inspektur Atribut yang diaktifkan secara default. Saya mencoba semua jawaban lain dan mereka tidak berhasil, akhirnya begini.
etayluz
15

Jika kelas Anda adalah subclass dari UICollectionviewController dan Anda membuat collectionView secara terprogram, gunakan

let layout = UICollectionViewFlowLayout()
    layout.scrollDirection = .Vertical
    layout.itemSize = CGSizeMake(50, 50)

    collectionView?.setCollectionViewLayout(layout, animated: false)
Gurjinder Singh
sumber
Ini adalah jawaban yang memecahkan masalah saya! Metode penggantian func collectionView (_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {<# code #>} tidak berfungsi untuk saya.
Mike
8

Saya menggunakan autolayout, dan dalam kasus saya, batasan tinggi tidak ada

AamirR
sumber
6

Masalah saya adalah saya memiliki 2 tampilan koleksi dalam tampilan yang sama, dan keduanya berbagi UICollectionViewFlowLayoutcontoh yang dihitung . Setelah saya membuat contoh terpisah dari tata letak aliran yang sama, itu berfungsi dengan baik.

nebyark
sumber
5

Dalam kasus saya, apa yang saya lupa lakukan dengan bodohnya adalah mengimplementasikan UICollectionViewDataSourcemetode protokol numberOfItemsInSection, jadi itu adalah hal lain untuk diperiksa.

Dekan
sumber
4

Selain itu, pastikan reloadData tidak dipanggil saat tampilan koleksi diperbarui dengan animasi (sisipkan, hapus, perbarui, atau performBatchUpdates).

sasha_nec
sumber
4

Dalam kasus saya, set collectionView.prefetchingEnabled = NO;memecahkan masalah saya. Hanya berfungsi di iOS 10.

6david9
sumber
2
Saya memberi suara positif untuk jawaban itu beberapa waktu lalu dan hari ini membantu saya lagi: D Anda berhak mendapatkan Noble untuk jawaban ini. Terima kasih lagi!
Maciek Czarnik
jawaban ini berhasil untuk saya! Saya berharap ada penjelasan tentang mengapa disertakan dengannya karena saya tidak pernah membuatnya menjadi benar untuk memulai.
Lance Samaria
3

Itu terjadi pada saya ketika tinggi item == 0 dengan memperbaiki metode cellForItem dipanggil.

Jirune
sumber
3

Sepuluh menit yang lalu saya juga mengalami masalah ini, saya melakukan kesalahan konyol.

Tujuan saya adalah menggunakan UICollectionViewFlowLayout,

Tetapi karena kesalahan, saya menggunakan UICollectionViewLayout.

Vincent Sit
sumber
3

Dalam kasus saya, mengubah tembus UINavigationBar menjadi NO memecahkan masalah.

chanil
sumber
3

Di Xcode 7.0.1, kami mendapatkan masalah ini saat kami menyalin papan cerita dan kode yang menyertai dari proyek lain. Tampilan koleksi memiliki tata letak aliran khusus yang disetel di papan cerita. Solusinya adalah:

  • Hapus tata letak aliran di IB
  • Kompilasi / jalankan aplikasi
  • Setel tata letak aliran kembali

Sekarang berhasil :)

Bart van Kuik
sumber
2

Pastikan juga numberOfSectionsInCollectionViewmengembalikan bilangan bulat positif.

Harus ada setidaknya satu bagian dalam koleksi.

Eran Goldin
sumber
2

Pastikan - (NSInteger) collectionView: numberOfItemsInSection: mengembalikan nilai positif (baca, lebih besar dari nol). Ini mungkin masalah penempatan [self.collectionView reloadData]; di penangan penyelesaian.

RT Denver
sumber
2

Saya lupa menyetel autoresizing mask ke false pada tampilan koleksi:

collectionView.translatesAutoresizingMaskIntoConstraints = false
Stritt
sumber
2

Ini bisa menjadi masalah tata letak yang nyata. Periksa peringatan tata letak dari konsol, jika ada.

erdikanik
sumber
2

Dalam kasus saya, tampilan koleksi tidak sepenuhnya terlihat dalam tampilan induknya karena kendala tata letak otomatis yang salah. Jadi memperbaiki batasan membuat tampilan koleksi semua terlihat dan cellForItemAtIndexPath dipanggil.

Khaled Annajar
sumber
2

Dalam properti storyboard / xib UICollectionView cellSize HARUS tidak {0, 0}

poGUIst
sumber
2

Jika Anda menggunakan protokol tampilan koleksi, Anda harus menghubungkan protokol CollectionViewDataSourcedan CollectionViewDelegateke ViewController Anda. Outlet pembuat antarmuka

Declan McKenna
sumber
1

Hal yang sama terjadi pada saya. Saya memiliki 2 UICollectionViews dan saya menghapusnya sekali karena saya tidak membutuhkannya. Setelah itu saya menyadari bahwa CellForItemAtIndexPath tidak dipanggil tetapi metode lain yang diperlukan. Saya mencoba semua hal di atas tetapi kemudian saya melakukan sihir standar. Menghapus tampilan koleksi dari storyboard dan ditambahkan lagi. Kemudian itu mulai bekerja. Tidak yakin mengapa dan saya tidak memiliki penjelasan tetapi mungkin beberapa masalah koneksi.

Hafeez
sumber
Saya menyalin UICollectionView saya dari UIViewController lain di storyboard. Saya menghapus CollectionView dan menambahkan lagi untuk membuatnya berfungsi. Terima kasih atas jawaban Anda.
Ayah Mabuk
1

Baru saja menyelesaikan masalah ini, untuk situasi yang agak spesifik.

Dalam kasus saya, saya secara manual menginisialisasi UICollectionViewController di ViewController induk, dan kemudian menambahkan tampilan UICollectionViewController sebagai subview.

Saya menyelesaikan masalah dengan memanggil 'setNeedsLayout' dan / atau 'setNeedsDisplay' di collectionView di viewDidAppear induk:

- (void)viewDidAppear:(BOOL)animated {
   [super viewDidAppear:animated];
   [_collection.view setNeedsLayout];
   [_collection.view setNeedsDisplay];
}
Tim
sumber
1

Saat menggunakan UICollectionViewDelegateFlowLayoutberhati-hatilah pada apa yang dikembalikan fungsi ini. Keduanya widthdan heightharus lebih besar dari 0. Saya digunakan windowsebagai referensi bingkai tetapi karena jendela hierarki tampilan yang rumit nilsaat runtime. Jika Anda perlu menyesuaikan lebar elemen berdasarkan penggunaan lebar layar UIScreen.main.bounds.

func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: 
           UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {}
inokey
sumber
1

Dalam kasus saya saya punya collectionViewdalam UIStackViewdengan alignment = .center. Jadi collectionViewtidak punya lebar. Saat mengatur stackView.alignmentke .fillsemuanya baik-baik saja.

Nico S.
sumber
0

Bagi saya, saya memperbarui tinggi self.view (superview collectionView) melalui autolayout, dan HARUS memanggilnya layoutIfNeededsetelah itu.

[self.view mas_updateConstraints:^(MASConstraintMaker *make) {
    make.height.equalTo(@(height));
}];
[self.view layoutIfNeeded];
Tuan Ming
sumber
0

Dalam kasus saya, saya harus menyesuaikan perkiraan ukuran Konten. ukuran konten tidak melakukannya.

  let layout = collectionVC.collectionView.collectionViewLayout as! UICollectionViewFlowLayout
    layout.itemSize = CGSize(width: 100, height: 100)
    layout.estimatedItemSize = CGSize(width: 100, height: 100)
tobi
sumber
0

Saya mengalami masalah serupa. Tapi malah cellForItemAtIndexPathdipanggil saat jumlah item> 1, tapi tidak saat item hanya ada satu. Saya mencoba banyak solusi yang diusulkan di sini dan mirip dengan banyak solusi yang saya temukan ada hubungannya dengan ukuran item. Bagi saya solusinya adalah mengubah ukuran perkiraan UICollectionViewdari Otomatis ke Kustom .

Setel perkiraan ukuran ke Kustom

Wouter
sumber
-1

Saya menghabiskan sedikit waktu dengan masalah yang akan datang ini dengan CollectionView dalam pengontrol tampilan Terkandung yang dimuat dari storyboard. Saya akhirnya hanya menghapus pengontrol tampilan yang ada, dan membuatnya kembali di storyboard, dan ini sepertinya menyingkirkan masalah. Dugaan saya adalah ada semacam korupsi papan cerita yang telah terjadi.

wfbarksdale.dll
sumber