Una de nuestras pantallas de aplicación requiere que coloquemos un UICollectionView
archivo UITableViewCell
. Esto UICollectionView
tendrá 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 UIViewController
esquema 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 UITableViewCell
funció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
UITableViewCell
tablero diferente de su vista de mesa real? ¿Necesita desplazamiento vertical tanto en elUICollectionView
como en elUITableView
Respuestas:
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 *)indexPath
Pero 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
UICollectionView
hastaUITableViewCell subclass
, dondeUICollectionView
se coloca. Deja, su nombre serácollectionView
Paso 2. Agregue IB para la
UICollectionView
restricción de altura y cree una salidaUITableViewCell subclass
también. Vamos, su nombre serácollectionViewHeight
.Paso 3. En
tableView:cellForRowAtIndexPath:
agregar código:fuente
collectionView
todos los lados deUITableViewCell
y establezcotableView.estimatedRowHeight = 44;
ytableView.rowHeight = UITableViewAutomaticDimension;
Tanto las vistas de tabla como las de colección son
UIScrollView
subclases 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
layoutAttributesForItemAtIndexPath
para 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 llamarlocollectionView
en lasystemLayoutSizeFitting
funció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.width
al establecer elcollectionView.frame
ancho de. También tuve que agregar los márgenes superior e inferior a laCGSize
altura 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
UICollectionViewFlowLayout
como diseño para la vista de su colección. Finalmente, asegúrese de vincularcollectionView
IBOutlet 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
UICollectionViewDelegateFlowLayout
yUICollectionViewDataSource
. ¡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:atIndexPath
vista 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
heightForRowAtIndexPath
para 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
collectionViewCellHeight
antes 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 sucollectionViewCell
cuenta con el borde de una regla.fuente