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?


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.


¿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


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.


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.


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;

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)

¡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


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.


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.


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).


4

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


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.


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.


3

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


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ó :)


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.


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.


2

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

collectionView.translatesAutoresizingMaskIntoConstraints = false

2

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


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.


2

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


2

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


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.


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

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 {}

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.


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

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)

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


-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.

Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.