No se llama a cellForItemAtIndexPath de UICollectionView

104

Solo es la segunda vez que uso UICollectionView's y quizás he mordido más de lo que puedo masticar, pero sin embargo:

Estoy implementando un UICollectionView (myCollectionView) que usa UICollectionViewCell personalizado que he subclasificado. Las celdas de subclases (FullReceiptCell) contienen UITableView y son del tamaño del controlador de vista. Estoy tratando de permitir el desplazamiento horizontal entre FullReceiptCells.

El UICollectionViewController subclasificado que contiene myCollectionView se está insertando en una pila de controlador de navegación. Actualmente, myCollectionView loas y el desplazamiento horizontal están habilitados. Sin embargo, no se ven celdas. He confirmado que

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

se ha ejecutado y está devolviendo un número entero mayor que 0. También he confirmado que el delegado y la fuente de datos de myCollectionView están configurados correctamente en IB para el UICollectionViewController subclasificado.

El método donde se cargarán las celdas:

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

no está siendo llamado.

Aquí es donde presiono el UICollectionViewController y mi método viewDidLoad dentro de ese controlador (NOTA: initWithBill es una anulación del inicializador normal):

En el archivo .m anterior de ViewControllers:

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

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

¿Alguna pista de por qué no se llama?

IkegawaTaro
fuente
Estoy usando XIB. No puedo quitar nada de la cola en cellForItemsAtIndexPath porque nunca se llama.
IkegawaTaro

Respuestas:

135

Para aquellos que tropiezan aquí más tarde ... la razón:

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

no se estaba llamando porque el itemSize de la colecciónViewFlowLayout era demasiado grande.

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

Si cambio la altura a 410, ejecutará cellForItemAtIndexPath.

IkegawaTaro
fuente
¿Puedes elaborar un poco más? Lo mismo me está sucediendo
user1010819
Acabo de descubrir que también debes tener cuidado con collectionViewContentSize
Dimitar Marinov
49
En caso de que esté utilizando el diseño automático, asegúrese de establecer una restricción de altura en la vista de colección, ¡desperdició muchas horas en esto!
bpn
porque la restricción de altura récord no funcionó para mí ... las restricciones de centro horizontal hicieron el truco
Mohamed Emad Hegab
4
Si su collectionView está restringida a topLayoutGuide con AutoLayout, y no se supone que se desplace debajo de NavigationBar, asegúrese de desmarcar Adjust Scroll View Insetsen su ViewController en Storyboard.
Bruno Galinari
96

En mi caso, fue porque mi clase de diseño subclasificó incorrectamente de en UICollectionViewLayoutlugar deUICollectionViewFlowLayout

esilver
fuente
1
GRACIAS. Que me jodan, pasé años en eso.
Rambatino
¡Este también era mi problema! Es un poco contradictorio, así que ni siquiera se me ocurrió. ¡Gracias por esto!
WendiKidd
¡Lo mismo para mi! ¡Es tan fácil pasar por alto eso! gracias de nuevo
arvidurs
Facepalm aquí, gracias por señalar esto (hace 4 años).
Milander
Estaba enfrentando el mismo problema. Gracias
Piyush Gupta
31

No se llamará a cellForItemAtIndexPath si no proporciona la información del tamaño del contenido a la vista de colección.

  1. Si está utilizando el diseño de flujo : debe configurar los tamaños de los elementos correctamente.
  2. Si tiene un diseño personalizado subclasificado de UICollectionViewLayout : asegúrese de que está devolviendo un tamaño adecuado del método collectionViewContentSize.

En el caso de este último, también observará que su layoutAttributesForElementsRect tampoco se llama. La razón es que no ha especificado cuál es el tamaño de su contenido y, por defecto, el tamaño será CGSizeZero. Básicamente, esto le dice a la vista de colección que no tiene ningún contenido para pintar, por lo que no se molesta en pedirle atributos o celdas.

Entonces, simplemente anule collectionViewContentSize y proporcione un tamaño adecuado allí, debería resolver su problema.

Deepak GM
fuente
1
Por ejemplo, para usar el tamaño completo disponible, devuelva collectionView.frame.size de collectionViewContentSize (no simplemente collectionView.contentSize, cuyo valor predeterminado es 0, 0)
Adam Loving
¡Gracias! Esta respuesta me ayudó porque tengo un UICollectionViewLayout personalizado. Si iniciaba la aplicación en el simulador en orientación horizontal, algunas celdas no aparecían en la vista inicial. Anular el tamaño del contenido solucionó este problema.
Chris Livdahl
1
Gracias. En mi caso, el collectionViewContentSize0 devuelto incorrectamente para el ancho, es por eso que cellForItemAtIndexPathno se llamaba.
izerik
16

Tal vez lo esté pasando por alto, pero parece que le falta su delegado y su fuente de datos. En su archivo de encabezado, asegúrese de haber agregado estos:

<UICollectionViewDelegate, UICollectionViewDataSource>

y en su método viewDidLoad agregue esto:

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

Además, si lo está cargando a través de un .xib, asegúrese de haber conectado IBOutlet a UICollectionView.

Anthony Castelli
fuente
1
No lo mostré, pero ya tengo el delegado y la fuente de datos anotados en el archivo de encabezado. Además, he conectado IBOutlet a myCollectionView. El delegado y la fuente de datos para esta vista de colección se han establecido en FullReceiptViewController. Lo extraño es que se llama a numberOfItemsInSection (un método de protocolo de fuente de datos) y se devuelve un número entero mayor que 0.
IkegawaTaro
Mmmm, cuando inicia la aplicación, ¿la vista Colección muestra o hace algo? Parece que tiene algunos elementos si numberOfItemsInSection devuelve algo mayor que 0.
Anthony Castelli
Gracias por hacer un seguimiento. La vista de colección muestra ... Puedo decirlo porque cambié el color de fondo. Creo que he encontrado el problema: [self.myCollectionViewFlowLayout setItemSize: CGSizeMake (320, 548)]; Esto era demasiado grande. Si reduzco la altura a 410, puedo hacer que se llame al método cellForItemAtIndexPath.
IkegawaTaro
@AnthonyCastelli Hola, también estoy enfrentando el mismo problema, se llama a numberOfItemsInSection en pop para viewController pero no cellForItemsAtIndexPath. ¿Entiendes la pista?
Bhavin Kansagara
16

Para obtener una jerarquía de vistas más complicada, consulte este blog . ¡Me salvó la vida!

self.automaticallyAdjustsScrollViewInsets = NO;
Jaybo
fuente
1
Pasé mucho tiempo en esto, y todo se redujo a eso. Si usa guión gráfico o XIB, mire el controlador de vista principal y anule la selección de "Ajustar inserciones de vista de desplazamiento" en el Inspector de atributos, que está activado de forma predeterminada. Probé todas las otras respuestas y no funcionaron, todo se redujo a esto.
etayluz
15

Si su clase es una subclase de UICollectionviewController y está creando collectionView programáticamente, use

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

    collectionView?.setCollectionViewLayout(layout, animated: false)
Gurjinder Singh
fuente
¡Esta es la respuesta que resolvió mi problema! El método de anulación func collectionView (_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {<# code #>} no funciona para mí.
Mike
8

Estaba usando el diseño automático y, en mi caso, faltaba la restricción de altura

AamirR
fuente
6

Mi problema era que tenía 2 vistas de colección dentro de la misma vista y ambas compartían una UICollectionViewFlowLayoutinstancia calculada . Una vez que creé instancias separadas del mismo diseño de flujo, funcionó bien.

nebyark
fuente
5

En mi caso, lo que me había olvidado estúpidamente de hacer era implementar el UICollectionViewDataSourcemétodo del protocolo numberOfItemsInSection, así que eso es otra cosa que verificar.

Decano
fuente
4

Además, asegúrese de que no se llame a reloadData mientras la vista de colección se actualiza con animación (insertar, eliminar, actualizar o realizarBatchUpdates).

sasha_nec
fuente
4

En mi caso, set collectionView.prefetchingEnabled = NO;resolvió mi problema. Solo funciona en iOS 10.

6david9
fuente
2
Elegí esa respuesta hace algún tiempo y hoy me ayudó nuevamente: D Te mereces un Noble por esta respuesta, hombre. ¡Gracias de nuevo!
Maciek Czarnik
esta respuesta funcionó para mí! Desearía que hubiera una explicación de por qué se incluyó con él porque nunca lo había configurado como verdadero para empezar.
Lance Samaria
3

Me estaba sucediendo cuando la altura del elemento == 0 al arreglar ese método cellForItem fue llamado.

Jirune
fuente
3

Hace diez minutos también encontré este problema, cometí un error tonto.

Mi intención es utilizar UICollectionViewFlowLayout,

Pero debido a errores, utilicé UICollectionViewLayout.

Vincent sentarse
fuente
3

En mi caso, cambiar el translúcido de UINavigationBar a NO resolvió el problema.

canal
fuente
3

En Xcode 7.0.1, obtuvimos este problema cuando copiamos un guión gráfico y el código adjunto de otro proyecto. La vista de colección tenía un diseño de flujo personalizado establecido en el guión gráfico. La solución fue:

  • Eliminar el diseño de flujo en IB
  • Compilar / ejecutar la aplicación
  • Volver a configurar el diseño de flujo

Ahora funcionó :)

Bart van Kuik
fuente
2

Asegúrese de que también numberOfSectionsInCollectionViewdevuelva un número entero positivo.

Tiene que haber al menos una sección en la colección.

Eran Goldin
fuente
2

Asegúrese de que - (NSInteger) collectionView: numberOfItemsInSection: devuelva un valor positivo (leído, mayor que cero). Puede ser cuestión de colocar [self.collectionView reloadData]; en el controlador de finalización.

RT Denver
fuente
2

Me olvidé de configurar la máscara de tamaño automático en falso en la vista de colección:

collectionView.translatesAutoresizingMaskIntoConstraints = false
Stritt
fuente
2

Se pueden relacionar problemas de diseño. Verifique las advertencias de diseño desde la consola, si existen.

erdikanik
fuente
2

En mi caso, la vista de la colección no era completamente visible en su vista principal debido a restricciones de diseño automático incorrectas. Así que arreglar las restricciones hizo que la vista de la colección fuera visible y se llamó a cellForItemAtIndexPath.

Khaled Annajar
fuente
2

En la propiedad de storyboard / xib UICollectionView cellSize no DEBE ser {0, 0}

poGUISTA
fuente
2

Si está utilizando protocolos de vista de colección, debe conectar los protocolos CollectionViewDataSourcey CollectionViewDelegatea su ViewController. Salidas del constructor de interfaces

Declan McKenna
fuente
1

Lo mismo me pasó a mí. Tenía 2 UICollectionViews y las eliminé una vez ya que no las necesitaba. Después de eso, me di cuenta de que no se llamaba a CellForItemAtIndexPath, sino a los otros métodos necesarios. Intenté todo lo anterior, pero luego hice la magia estándar. Se eliminó la vista de colección del guión gráfico y se agregó nuevamente. Entonces empezó a funcionar. No estoy seguro de por qué y no tengo una explicación, pero tal vez algunos problemas de conexión.

Hafeez
fuente
Copié mi UICollectionView de otro UIViewController en el guión gráfico. Eliminé CollectionView y lo agregué nuevamente para que funcione. Gracias por su respuesta.
Drunken Daddy
1

Acabo de resolver este problema, para una situación algo específica.

En mi caso, estaba inicializando manualmente el UICollectionViewController en un ViewController principal y luego agregando la vista de UICollectionViewController como una subvista.

Resolví el problema llamando a 'setNeedsLayout' y / o 'setNeedsDisplay' en collectionView en el viewDidAppear del padre:

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

Al usar, UICollectionViewDelegateFlowLayouttenga cuidado con lo que devuelve esta función. Ambos widthy heightdebería ser mayor que 0. Lo usé windowcomo referencia de marco, pero debido a la complicada jerarquía de vistas, la ventana estaba nilen tiempo de ejecución. Si necesita ajustar el ancho del elemento en función del ancho de la pantalla, utilice UIScreen.main.bounds.

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

En mi caso tuve el collectionViewin a UIStackViewcon alignment = .center. Entonces el collectionViewno tenía ancho. Al configurar el stackView.alignmenta .filltodo estaba bien.

Nico S.
fuente
0

Para mí, actualizo la altura de self.view (la supervista de collectionView) a través de autolayout, y DEBO llamar layoutIfNeededdespués de eso.

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

En mi caso, tuve que ajustar el tamaño estimado del Contenido. el tamaño del contenido no lo hizo.

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

Tenía un problema similar. Pero en su lugar cellForItemAtIndexPathse llamó cuando la cantidad de elementos era> 1, pero no cuando solo había un elemento. Probé muchas de las soluciones propuestas aquí y, al igual que muchas, descubrí que tenían que ver con el tamaño del artículo. Para mí, la solución fue cambiar el tamaño estimado UICollectionViewde Automático a Personalizado .

Establecer tamaño estimado en Personalizado

Wouter
fuente
-1

Perdí un poco de tiempo con este problema con un CollectionView en un controlador de vista contenido cargado desde un guión gráfico. Terminé simplemente eliminando el controlador de vista contenido y recrearlo en el guión gráfico, y esto pareció solucionar el problema. Supongo que se produjo algún tipo de corrupción en el guión gráfico.

wfbarksdale
fuente