UICollectionView'ın cellForItemAtIndexPath'i çağrılmıyor


104

UICollectionView'i sadece ikinci kez kullanıyorum ve belki de çiğneyebileceğimden daha fazla ısırdım ama yine de:

Alt sınıflara sahip olduğum özel UICollectionViewCell kullanan bir UICollectionView (myCollectionView) uyguluyorum. Alt sınıflı hücreler (FullReceiptCell) UITableView'leri içerir ve görünüm denetleyicisinin boyutudur. FullReceiptCells arasında yatay kaydırmaya izin vermeye çalışıyorum.

MyCollectionView içeren alt sınıflı UICollectionViewController, bir nav denetleyici yığınına itiliyor. Şu anda myCollectionView loas ve yatay kaydırma etkindir. Ancak, hiçbir hücre görünmez. Bunu teyit ettim

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

çalıştırdı ve 0'dan büyük bir tamsayı döndürüyor. myCollectionView'ın temsilcisinin ve veri kaynağının IB'de alt sınıflı UICollectionViewController'a düzgün şekilde ayarlandığını da onayladım.

Hücrelerin yükleneceği yöntem:

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

aranmıyor.

UICollectionViewController'ı ve bu denetleyicideki viewDidLoad yöntemimi ittiğim yer burasıdır (NOT: initWithBill, normal başlatıcının geçersiz kılınmasıdır):

Önceki ViewControllers .m dosyasında:

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

FullReceiptViewController.m'de:

- (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];

Neden aranmadığına dair bir ipucu?


XIB kullanıyorum. CellForItemsAtIndexPath içindeki hiçbir şeyi sıraya alamıyorum çünkü hiçbir zaman çağrılmıyor.
IkegawaTaro

Yanıtlar:


135

Burada daha sonra tökezleyenler için .... nedeni:

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

collectionViewFlowLayout için itemSize yüksekliği çok büyük olduğu için çağrılmıyordu.

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

Yüksekliği 410 olarak değiştirirsem, cellForItemAtIndexPath çalıştıracaktır.


Biraz daha detaylandırır mısınız? Benim için de aynı şey oluyor
user1010819

CollectionViewContentSize konusunda da dikkatli olmanız gerektiğini keşfettim
Dimitar Marinov 14

49
Otomatik düzen kullanıyorsanız - collectionView'da bir yükseklik kısıtlaması ayarladığınızdan emin olun - bu konuda saatler harcadı!
bpn

rekor yükseklik kısıtlaması benim için işe yaramadı .. yatay merkez kısıtlamaları işe yaradı
Mohamed Emad Hegab

4
CollectionView'unuz AutoLayout ile topLayoutGuide ile sınırlandırılmışsa ve NavigationBar altında kaydırılması gerekmiyorsa Adjust Scroll View Insets, Storyboard'da ViewController'ınızın işaretini kaldırdığınızdan emin olun .
Bruno Galinari

96

Benim durumumda, bunun nedeni, düzen sınıfımın UICollectionViewLayoutyerineUICollectionViewFlowLayout


1
TEŞEKKÜR EDERİM. Kahretsin, bunun için yaşlarımı harcadım.
Rambatino

Bu benim de sorunumdu! Bu biraz mantık dışı, bu yüzden aklıma bile gelmedi. Bunun için teşekkürler!
WendiKidd

Benim için aynı! bunu gözden kaçırmak çok kolay! tekrar teşekkürler
arvidurs

Facepalm burada, buna işaret ettiğiniz için teşekkür ederim (4 yıl önce).
Milander

Ben de aynı sorunla karşı karşıyaydım. Teşekkürler
Piyush Gupta

31

Koleksiyon görünümüne içerik boyutu bilgilerini sağlamazsanız, cellForItemAtIndexPath çağrılmaz.

  1. Akış düzenini kullanıyorsanız : Öğe boyutlarını doğru şekilde ayarlamanız gerekir.
  2. UICollectionViewLayout'tan alt sınıflara ayrılmış özel bir düzeniniz varsa : collectionViewContentSize yönteminden uygun bir boyut döndürdüğünüzden emin olun.

İkincisi durumunda, layoutAttributesForElementsRect'inizin de de çağrılmadığını . Bunun nedeni, içerik boyutunuzun ne olduğunu belirtmemiş olmanız ve varsayılan olarak boyutun CGSizeZero olacağıdır. Bu, temel olarak koleksiyon görünümüne boyayacak herhangi bir içeriğiniz olmadığını söyler, bu nedenle sizden öznitelikler veya hücreler sorma zahmetine girmez.

Yani, sadece collectionViewContentSize değerini geçersiz kılın ve orada uygun bir boyut sağlayın, sorununuzu çözmelidir.


1
Örneğin tam kullanılabilir boyutu kullanmak için collectionViewContentSize öğesinden collectionView.frame.size döndürün (yalnızca collectionView.contentSize değil, varsayılan değer 0, 0'dır)
Adam Loving

Teşekkürler! Bu cevap bana yardımcı oldu, b / c özel bir UICollectionViewLayout'um var. Uygulamayı simülatörde yatay yönde başlatırsam, bazı hücreler ilk görünümde görünmüyordu. İçerik boyutunu geçersiz kılmak bu sorunu benim için çözdü.
Chris Livdahl

1
Teşekkür ederim. Benim durumumda collectionViewContentSizegenişlik için yanlış olarak 0 döndürüldü, bu yüzden cellForItemAtIndexPathçağrılmadı.
izerik

16

Belki sadece gözden kaçırıyorum ama görünüşe göre temsilciniz ve veri kaynağınız eksik. Başlık dosyanıza şunları eklediğinizden emin olun:

<UICollectionViewDelegate, UICollectionViewDataSource>

ve viewDidLoad yönteminize şunu ekleyin:

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

Ayrıca, bir .xib aracılığıyla yüklüyorsanız, IBOutlet'i UICollectionView'e bağladığınızdan emin olun.


1
Göstermedim ama zaten üstbilgi dosyasında not edilen temsilci ve veri kaynağına sahibim. Ek olarak, IBOutlet'i myCollectionView'a bağladım. Bu koleksiyon görünümü için temsilci ve veri kaynağı FullReceiptViewController olarak ayarlandı. Garip olan şey, numberOfItemsInSection'ın (bir veri kaynağı protokol yöntemi) çağrılması ve 0'dan büyük bir tamsayı döndürmesidir.
IkegawaTaro

Hmm, uygulamayı başlattığınızda Koleksiyon görünümü herhangi bir şey gösteriyor mu? NumberOfItemsInSection 0'dan büyük bir değer döndürürse, içinde bazı öğeler varmış gibi görünüyor.
Anthony Castelli

Takip ettiğiniz için teşekkürler. Koleksiyon görünümü gösteriyor ... Arka plan rengini değiştirdiğim için anlayabiliyorum. Sorunu bulduğuma inanıyorum: [self.myCollectionViewFlowLayout setItemSize: CGSizeMake (320, 548)]; Bu çok büyüktü. Yüksekliği 410'a düşürürsem, cellForItemAtIndexPath yönteminin çağrılmasını sağlayabilirim.
IkegawaTaro

@AnthonyCastelli Merhaba, ben de aynı sorunla karşı karşıyayım, numberOfItemsInSection pop'da viewController'a çağrılıyor ama cellForItemsAtIndexPath değil. peki ipucunu anladın mı?
Bhavin Kansagara

16

Daha karmaşık bir görünüm hiyerarşisi için lütfen bu bloga bakın . Hayatımı kurtardı!

self.automaticallyAdjustsScrollViewInsets = NO;

1
Bunun için çok zaman harcadım - ve hepsi buna bağlı. Film şeridi veya XIB kullanıyorsanız, üst görünüm denetleyicisine bakın ve varsayılan olarak açık olan Öznitelik Denetçisinde "Kaydırma Görünümü Eklemelerini Ayarla" seçeneğinin işaretini kaldırın. Diğer tüm cevapları denedim ve işe yaramadı, işte bu geldi.
etayluz

15

Sınıfınız UICollectionviewController'ın alt sınıfı ise ve programlı olarak collectionView oluşturuyorsanız, ardından şunu kullanın:

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

    collectionView?.setCollectionViewLayout(layout, animated: false)

Bu cevap sorunumu çözdü! Geçersiz kılma yöntemi func collectionView (_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {<# code #>} benim için çalışmıyor.
Mike

8

Otomatik düzen kullanıyordum ve benim durumumda yükseklik kısıtlaması eksikti


6

Sorunum, aynı görünümde 2 koleksiyon görünümümün olması ve her ikisinin de hesaplanmış bir UICollectionViewFlowLayoutörneği paylaşmasıydı . Aynı akış düzeninin ayrı örneklerini oluşturduktan sonra iyi çalıştı.


5

Benim durumumda, aptalca yapmayı unuttuğum şey, UICollectionViewDataSourceprotokol yöntemini uygulamaktı numberOfItemsInSection, bu yüzden kontrol etmem gereken başka bir şey bu.


4

Ayrıca, koleksiyon görünümü animasyonla güncellenirken reloadData'nın çağrılmadığından emin olun (insert, delete, update veya performBatchUpdates).


4

Benim durumumda set collectionView.prefetchingEnabled = NO;sorunumu çözdü. Yalnızca iOS 10'da çalışır.


2
Bu yanıta bir süre önce oy verdim ve bugün yine bana yardımcı oldu: D Bu cevap için bir Noble'ı hak ediyorsun dostum. Tekrar teşekkürler!
Maciek Czarnik

bu cevap benim için çalıştı! Keşke buna neden dahil edildiğine dair bir açıklama olsaydı, çünkü başlangıçta bunu asla doğru olarak ayarlamamıştım.
Lance Samaria

3

Bu cellForItem yöntemi çağrıldığında öğe yüksekliği == 0 olduğunda benim için oluyordu.


3

On dakika önce ben de bu sorunla karşılaştım, aptalca bir hata yaptım.

Niyetim UICollectionViewFlowLayout'u kullanmak,

Ama hatalar yüzünden UICollectionViewLayout kullandım.


3

Benim durumumda, UINavigationBar'ın yarı saydamını NO olarak değiştirmek sorunu çözdü.


3

Xcode 7.0.1'de, başka bir projeden bir storyboard ve beraberindeki kodu kopyaladığımızda bu sorunu yaşadık. Koleksiyon görünümünün film şeridinde ayarlanmış özel bir akış düzeni vardı. Çözüm şöyleydi:

  • IB'deki akış düzenini kaldırın
  • Uygulamayı derleyin / çalıştırın
  • Akış düzenini geri ayarlayın

Şimdi işe yaradı :)


2

Ayrıca numberOfSectionsInCollectionViewpozitif bir tamsayı döndürdüğünden emin olun .

Koleksiyonda en az bir bölüm bulunmalıdır.


2

- (NSInteger) collectionView: numberOfItemsInSection: pozitif (okuma, sıfırdan büyük) bir değer döndürdüğünden emin olun. [Self.collectionView reloadData] 'nın yerleştirilmesi meselesi olabilir; tamamlama işleyicisinde.


2

Koleksiyon görünümünde otomatik yeniden boyutlandırma maskesini yanlış olarak ayarlamayı unuttum:

collectionView.translatesAutoresizingMaskIntoConstraints = false

2

Gerçekleştirilen yerleşim problemleri olabilir. Varsa, konsoldan düzen uyarılarını kontrol edin.


2

Benim durumumda koleksiyon görünümü, yanlış otomatik düzen kısıtlamaları nedeniyle üst görünümünde tam olarak görünmüyordu. Böylece kısıtlamaların düzeltilmesi koleksiyon görünümünü tüm görünür hale getirdi ve cellForItemAtIndexPath çağrıldı.


2

Film şeridi / xib'de UICollectionView özelliği cellSize {0, 0} OLMAMALIDIR


2

Koleksiyon görünümü protokollerini kullanıyorsanız CollectionViewDataSourceve CollectionViewDelegateprotokollerini ViewController cihazınıza bağlamanız gerekir . Arayüz oluşturucu çıkışları


1

Aynısı bana da oldu. 2 UICollectionViews vardı ve buna ihtiyacım olmadığı için bir kez kaldırdım. Bundan sonra CellForItemAtIndexPath'in çağrılmadığını, diğer gerekli yöntemlerin çağrıldığını fark ettim. Yukarıdakilerin hepsini denedim ama sonra standart sihri yaptım. Koleksiyon görünümü film şeridinden kaldırıldı ve tekrar eklendi. Sonra çalışmaya başladı. Neden olduğundan emin değilim ve açıklamam yok ama belki bazı bağlantı sorunları olabilir.


UICollectionView'umu film şeridindeki başka bir UIViewController'dan kopyaladım. CollectionView'ı sildim ve çalışması için tekrar ekledim. Cevabınız için teşekkür ederim.
Sarhoş Baba

1

Biraz özel bir durum için bu sorunu çözdüm.

Benim durumumda, UICollectionViewController'ı bir üst ViewController'da manuel olarak başlatıyor ve ardından UICollectionViewController görünümünü bir alt görünüm olarak ekliyordum.

Ebeveynin viewDidAppear'ında collectionView'da 'setNeedsLayout' ve / veya 'setNeedsDisplay' çağırarak sorunu çözdüm:

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

1

Kullanırken UICollectionViewDelegateFlowLayoutbu işlevin ne döndürdüğüne dikkat edin. İkisi de widthve heightdaha büyük olmalıdır 0. windowÇerçeve referansı olarak kullandım , ancak karmaşık görünüm hiyerarşisi nedeniyle penceresi nilçalışma zamanında idi. Öğenin genişliğini ekran genişliği kullanımına göre ayarlamanız gerekiyorsa UIScreen.main.bounds.

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

1

Ben de benzer bir sorun yaşıyordum. Ancak bunun yerine cellForItemAtIndexPath, öğe sayısı> 1 olduğunda çağrıldı, ancak yalnızca tek bir öğe olduğunda çağrılmadı. Önerilen çözümlerin çoğunu burada denedim ve çoğuna benzer şekilde öğe boyutlandırmayla ilgili olduğunu öğrendim. Benim için çözüm tahmini boyutunu değiştirmek oldu UICollectionViewdan Otomatik için Custom .

Tahmin boyutunu Özel olarak ayarlayın


Ben de tamamen aynı sorunu yaşadım, teşekkürler!
Mykola Denysyuk

1

Benim durumumda vardı collectionViewbir de UIStackViewsahip alignment = .center. Yani collectionViewbir genişliği yoktu. Ayarlarken stackView.alignmentiçin .fillher şey iyiydi.


0

Benim için self.view'un yüksekliğini (collectionView'in süpervizörünü) otomatik düzen yoluyla güncelliyorum ve layoutIfNeededbundan sonra ÇAĞIRMALIDIR .

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

0

Benim durumumda tahmini İçerik boyutunu ayarlamam gerekiyordu. içerik boyutu bunu yapmadı.

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

-1

Bir storyboard'dan yüklenen bir Kapsayıcı görünüm denetleyicisinde bir CollectionView ile birlikte gelen bu sorunla biraz zaman geçirdim. İçerdiği görünüm denetleyicisini silerek ve film şeridinde yeniden oluşturdum ve bu sorundan kurtulmuş gibi görünüyordu. Tahminimce bir tür storyboard bozulması meydana geldi.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.