Una de nuestras pantallas de aplicación requiere que coloquemos un UICollectionViewarchivo UITableViewCell. Esto UICollectionViewtendrá un número dinámico de elementos, lo que dará como resultado una altura que también debe calcularse dinámicamente. Sin embargo, tengo problemas al intentar calcular la altura del archivo UICollectionView.
Nuestro UIViewControlleresquema general se creó en Storyboards y hace uso del diseño automático. Pero, no sé cómo aumentar dinámicamente la altura de la en UITableViewCellfunción de la altura de UICollectionView.
¿Alguien puede dar algunos consejos o consejos sobre cómo lograr esto?
                    
                        ios
                                uitableview
                                uicollectionview
                                
                    
                    
                        Hombre de la sombra
fuente
                
                fuente

UITableViewCelltablero diferente de su vista de mesa real? ¿Necesita desplazamiento vertical tanto en elUICollectionViewcomo en elUITableViewRespuestas:
La respuesta correcta es SÍ , PUEDE hacer esto.
Me encontré con este problema hace algunas semanas. En realidad, es más fácil de lo que piensas. Coloque sus celdas en NIB (o guiones gráficos) y fíjelas para permitir que el diseño automático haga todo el trabajo
Dada la siguiente estructura:
La solución es decirle al diseño automático que calcule primero los tamaños de collectionViewCell, luego la vista de colección contentSize, y utilícela como el tamaño de su celda. Este es el método UIView que "hace la magia":
Debe establecer aquí el tamaño de TableViewCell, que en su caso es contentSize de CollectionView.
ColecciónViewCell
En CollectionViewCell , debe indicarle a la celda que se diseñe cada vez que cambie el modelo (por ejemplo: establece un UILabel con un texto, luego la celda tiene que ser diseñada nuevamente).
TableViewCell
El TableViewCell hace la magia. Tiene una salida a su collectionView, habilita el diseño automático para las celdas de collectionView utilizando estimadoItemSize de UICollectionViewFlowLayout .
Entonces, el truco consiste en establecer el tamaño de la celda tableView en el método systemLayoutSizeFittingSize ... (NOTA: iOS8 o posterior)
NOTA: Traté de usar el método de altura de la celda delegada de tableView.
-(CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPathPero es demasiado tarde para que el sistema de diseño automático calcule el tamaño del contenido de CollectionView y, a veces, puede encontrar celdas redimensionadas incorrectas.TableViewController
Recuerde habilitar el sistema de diseño automático para las celdas tableView en su TableViewController :
CRÉDITO: @rbarbera ayudó a solucionar esto
fuente
cell.bounds = CGRectMake(0, 0, CGRectGetWidth(tableView.bounds), 10000);esto "simulará" una celda larga con una vista de colección larga, por lo que la vista de colección calculará el tamaño de todas sus celdas. De lo contrario, collectionView calculó solo los tamaños de celda visibles y estableció incorrectamente la altura de talbeViewCell.systemLayoutSizeFittingSize, tengo un problema rápido al recargar la celda, las aplicaciones parecen atascarse después deself.collectionView.layoutIfNeeded(). Lo arreglé estableciendo la altura del marco con 1 en lugar de la altura máxima. Espero que sea de ayuda si alguien tropieza con este problema.systemLayoutSizeFitting, invierta el orden de lo que se muestra en la respuesta actualmente, de modo que primero secollectionView.layoutIfNeeded()ejecute, luegocollectionView.frame = CGRect.init(origin: .zero, size: CGSize.init(width: targetSize.width, height: 1))Creo que mi solución es mucho más simple que la propuesta por @PabloRomeu.
Paso 1. Cree una salida desde
UICollectionViewhastaUITableViewCell subclass, dondeUICollectionViewse coloca. Deja, su nombre serácollectionViewPaso 2. Agregue IB para la
UICollectionViewrestricción de altura y cree una salidaUITableViewCell subclasstambién. Vamos, su nombre serácollectionViewHeight.Paso 3. En
tableView:cellForRowAtIndexPath:agregar código:fuente
collectionViewtodos los lados deUITableViewCelly establezcotableView.estimatedRowHeight = 44;ytableView.rowHeight = UITableViewAutomaticDimension;Tanto las vistas de tabla como las de colección son
UIScrollViewsubclases y, por lo tanto, no les gusta estar incrustadas dentro de otra vista de desplazamiento, ya que intentan calcular el tamaño del contenido, reutilizar celdas, etc.Te recomiendo que uses solo una vista de colección para todos tus propósitos.
Puede dividirlo en secciones y "tratar" el diseño de algunas secciones como una vista de tabla y otras como una vista de colección. Después de todo, no hay nada que no pueda lograr con una vista de colección que pueda con una vista de tabla.
Si tiene un diseño de cuadrícula básico para las "partes" de la vista de colección, también puede usar celdas normales de la tabla para manejarlas. Aún así, si no necesita la compatibilidad con iOS 5, debería usar mejor las vistas de colección.
fuente
layoutAttributesForItemAtIndexPathpara diferentes secciones en mi propia subclase personalizada deUICollectionViewLayout?La respuesta de Pablo Romeu anterior ( https://stackoverflow.com/a/33364092/2704206 ) me ayudó enormemente con mi problema. Sin embargo, tuve que hacer algunas cosas de manera diferente para que esto funcionara para mi problema. En primer lugar, no tuve que llamar
layoutIfNeeded()tan a menudo. Solo tuve que llamarlocollectionViewen lasystemLayoutSizeFittingfunción.En segundo lugar, tenía restricciones de diseño automático en mi vista de colección en la celda de vista de tabla para darle algo de relleno. Así que tuve que restar los márgenes inicial y final del
targetSize.widthal establecer elcollectionView.frameancho de. También tuve que agregar los márgenes superior e inferior a laCGSizealtura del valor de retorno .Para obtener estas constantes de restricción, tuve la opción de crear salidas para las restricciones, codificar sus constantes o buscarlas por un identificador. Decidí optar por la tercera opción para hacer que mi clase de celda de vista de tabla personalizada sea fácilmente reutilizable. Al final, esto fue todo lo que necesitaba para que funcionara:
Como función auxiliar para recuperar una restricción por identificador, agrego la siguiente extensión:
NOTA: Deberá establecer el identificador en estas restricciones en su guión gráfico o donde sea que se creen. A menos que tengan una constante 0, no importa. Además, como en la respuesta de Pablo, deberá usarlo
UICollectionViewFlowLayoutcomo diseño para la vista de su colección. Finalmente, asegúrese de vincularcollectionViewIBOutlet a su guión gráfico.Con la celda de vista de tabla personalizada anterior, ahora puedo subclasificarla en cualquier otra celda de vista de tabla que necesite una vista de colección y hacer que implemente los protocolos
UICollectionViewDelegateFlowLayoutyUICollectionViewDataSource. ¡Espero que esto sea útil para alguien más!fuente
Leí todas las respuestas. Esto parece servir para todos los casos.
fuente
Una alternativa a la solución de Pablo Romeu es personalizar UICollectionView en sí, en lugar de hacer el trabajo en la celda de vista de tabla.
El problema subyacente es que, de forma predeterminada, una vista de colección no tiene un tamaño intrínseco y, por lo tanto, no puede informar el diseño automático de las dimensiones a utilizar. Puede remediarlo creando una subclase personalizada que devuelva un tamaño intrínseco útil.
Cree una subclase de UICollectionView y anule los siguientes métodos
(También debe anular los métodos relacionados: reloadSections, reloadItemsAtIndexPaths de manera similar a reloadData ())
Llamar a layoutIfNeeded obliga a la vista de colección a recalcular el tamaño del contenido que luego se puede usar como el nuevo tamaño intrínseco.
Además, debe manejar explícitamente los cambios en el tamaño de la vista (por ejemplo, en la rotación del dispositivo) en el controlador de vista de tabla
fuente
Recientemente me enfrenté al mismo problema y casi probé todas las soluciones en las respuestas, algunas de ellas funcionaron y otras no, mi principal preocupación sobre el enfoque de @PabloRomeu es que si tiene otros contenidos en la celda (además de la vista de colección) tendrá que calcular sus alturas y las alturas de sus restricciones y devolver el resultado para obtener el diseño automático correcto y no me gusta calcular las cosas manualmente en mi código. Así que aquí está la solución que funcionó bien para mí sin hacer ningún cálculo manual en mi código.
en la
cellForRow:atIndexPathvista de tabla hago lo siguiente:Creo que lo que sucede aquí es que obligo a la celda de la vista de tabla a ajustar su altura después de que se haya calculado la altura de la vista de la colección. (después de proporcionar la fecha de collectionView a la fuente de datos)
fuente
Pondría un método estático en la clase de vista de colección que devolverá un tamaño basado en el contenido que tendrá. Luego use ese método en el
heightForRowAtIndexPathpara devolver el tamaño adecuado.También tenga en cuenta que puede tener un comportamiento extraño cuando inserta este tipo de viewControllers. Lo hice una vez y tuve algunos problemas de memoria extraños que nunca resolví.
fuente
Quizás mi variante sea útil; He estado decidiendo esta tarea durante las últimas dos horas. No pretendo que sea 100% correcto u óptimo, pero mi habilidad es muy pequeña todavía y me gustaría escuchar comentarios de expertos. Gracias. Una nota importante: esto funciona para tablas estáticas, está especificado por mi trabajo actual. Entonces, todo lo que uso es viewWillLayoutSubviews de tableView . Y un poquito más.
fuente
El enfoque más fácil que se me ocurrió, hasta ahora, Créditos para la respuesta de @igor anterior,
En su clase tableviewcell simplemente inserte esto
y, por supuesto, cambie la vista de la colección con su salida en la clase de la celda
fuente
Tengo una idea de la publicación de @Igor e invierto mi tiempo en esto para mi proyecto con swift
Solo pasa esto en tu
Además: si ve su UICollectionView entrecortado al cargar celdas.
fuente
La solución de Pablo no me funcionó muy bien, tuve efectos visuales extraños (la vista de colección no se ajustaba correctamente).
Lo que funcionó fue ajustar la restricción de altura de collectionView (como NSLayoutConstraint) a collectionView contentSize durante
layoutSubviews(). Este es el método llamado cuando se aplica el diseño automático a la celda.fuente
En su UITableViewDelegate:
Sustituya itemCount y CollectionViewCellHeight con los valores reales. Si tiene una matriz de matrices, itemCount podría ser:
O lo que sea.
fuente
collectionViewCellHeightantes de renderizar.1.Crear celda ficticia.
Utilice el método collectionViewContentSize en UICollectionViewLayout de UICollectionView utilizando datos actuales.
fuente
Se puede calcular la altura de la colección basada en sus propiedades como
itemSize,sectionInset,minimumLineSpacing,minimumInteritemSpacing, si sucollectionViewCellcuenta con el borde de una regla.fuente