Las subviews de celdas de UICollectionView no cambian de tamaño


En un CollectionView, algunas celdas deben tener una subview o capa adicional. A CollectionView se le puede decir que cambie el tamaño de sus celdas, por lo tanto, todo el contenido debe cambiar el tamaño apropiadamente.

Actualmente, la celda se inicializa desde un nib que contiene una celda con imageview; el nib de celda está vinculado a una subclase personalizada UICollectionViewCell, que solo hace el init. Autoresize subviews está marcada.

Al CollectionView se le dice que cambie el tamaño de la celda por un valor derivado y devuelto en sizeForItemAtIndexPath:. He subclasificado un FlowLayout pero solo especifica ScrollDirection y Insets.

Todo eso está funcionando bien. Problema: ¿Cómo agrego subview/layer a la celda para que también cambie de tamaño correctamente? Intenté agregar subviews y capas con translatesAutoresizingMaskIntoConstraints desactivado, pero estos no cambian automáticamente el tamaño en absoluto. También se trató de utilizar el marco de código / vista en lugar de nib.

Lo mejor que tengo ahora es una subcapa cell.contentView.layer que agrego en cellForItemAtIndexPath:; que se redimensiona "manualmente" almacenando el frame.size de la celda de sizeForItemAtIndexPath:, que no solo es feo sino que también termina con el subcapa que tiene varios tamaños para diferentes células.

Cualquier ayuda apreciada!

Author: Forge, 2013-03-09

10 answers

Acabo de encontrarme con el mismo problema.

Cuando se utiliza el método UICollectionViewFlowLayoutDelegate para establecer el tamaño de la celda dependiendo del dispositivo y la orientación del dispositivo, el tamaño se calculará correctamente, pero las subviews no se redimensionarán para llenar la celda de nuevo tamaño. El efecto fue una celda en blanco grande con pequeñas subviews que no llenan los límites de la celda / siguen siendo el tamaño igual a su valor actual en el archivo xib.

Resolví esto haciendo lo siguiente en awakeFromNib:

- (void)awakeFromNib
{
    [super awakeFromNib];

    self.contentView.autoresizingMask = UIViewAutoresizingFlexibleHeight | UIViewAutoresizingFlexibleWidth;
    self.contentView.translatesAutoresizingMaskIntoConstraints = YES;
}

Antes de hacer esto, la máscara contentView era nil.

 80
Author: Alfie Hanssen,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-09-10 20:26:25
*override func awakeFromNib() {
    super.awakeFromNib()

    self.contentView.autoresizingMask.insert(.FlexibleHeight)
    self.contentView.autoresizingMask.insert(.FlexibleWidth)
}

Esto funcionó para mí.. Este código va dentro de su subclase UICollectionViewCell.archivo swift (donde se encuentra su código que involucra la celda personalizada)

Solución rápida *

 16
Author: NSCoyote,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-03-24 22:23:07

Como alternativa a habilitar autoresizingMask, para los diseños personalizados de UICollectionViewLayouts que tienen una altura variable, por ejemplo, donde está configurando algunas restricciones manualmente y necesita translatesAutoresizingMaskIntoConstraints para permanecer NO, puede agregar lo siguiente a layoutSubviews en la celda:

self.contentView.frame = self.bounds;

Esto funcionó para arreglar todos mis diseños de vista de colección personalizados que tenían problemas con Xcode 6.

 6
Author: Praneeth Wanigasekera,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-10-28 02:38:17

En otro proyecto sin xibs subclase UICollectionViewCell e hice esto para el mismo efecto:

#import "CVcell.h"

@implementation CVcell

@synthesize cellImage;

- (id)initWithFrame:(CGRect)frame
{
    self = [super initWithFrame:frame];
    if (self) {

        CGFloat cellSize = self.contentView.bounds.size.width;
        cellImage = [[UIImageView alloc]initWithFrame:CGRectMake(0, 0, cellSize, cellSize)];
        [cellImage setClipsToBounds:YES];

        cellImage.translatesAutoresizingMaskIntoConstraints = NO;
        cellImage.autoresizingMask = UIViewAutoresizingFlexibleHeight | UIViewAutoresizingFlexibleWidth;
        [self.contentView addSubview:cellImage];

    }
    return self;
}

@end
 4
Author: ceekay,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-01-25 20:20:16

Siempre prefiero el diseño automático cuando sea posible. Pero A veces usar marcos y límites solo es un ahorrador de tiempo cuando una vista está determinada directamente solo por su supervisión.

En el caso de UICollectionViewCell establezco una imagen para que sea el marco de celdas + self.imageView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;

Pero cuando tenía diferentes tamaños de celdas en la collectionView, arruinaba las cosas y la imagen a veces tomaba el tamaño de una celda diferente.

Así que me volví a trabajar con los límites de las celdas y-ye eso funcionó bien.

Así que tal vez darle una oportunidad?

 3
Author: Pedroinpeace,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-03-06 10:12:51

Una solución sencilla de diseño automático consiste en establecer restricciones en la vista contenedor.

Así que si tenemos una vista de imagen con una vista padre, básicamente queremos decirle a la vista inferior (la vista de imagen) que mantenga una distancia de espacio inicial, final, inferior y superior de 0 a la vista contenedor.

Restricciones de diseño automático para cambiar el tamaño con la vista principal

 3
Author: jlmendezbonini,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-04-15 00:01:04

@Alfie Hanssen solución (aquí) no funcionó correctamente para mí, de acuerdo con este artículo :

El tamaño de la vista de celda en el XIB es de 50 x 50 puntos, que es el tamaño predeterminado de las celdas de la vista de colección como se establece en el diseño de flujo. Incluso si es un poco difícil trabajar con una celda tan pequeña en Interface Builder, es mejor no cambiar el tamaño predeterminado. El problema es que el diseño automático considera el tamaño establecido manualmente como fijo y genera un NSAutoresizingMaskLayoutConstraint error cuando intenta ajustar la altura de las celdas automáticamente

He inspeccionado la UICollectionViewCell y he encontrado que hay una vista entre la celda y la contentView, y esa vista tiene restricciones intrínsecas de ancho y altura. En lugar de la máscara de autoresizing, solo estoy actualizando como se muestra a continuación y parece que funciona para mí.

override func layoutSubviews() {
    contentView.superview?.frame = bounds
    super.layoutSubviews()
}
 2
Author: Serluca,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-05-23 12:10:12

La solución fue desactivar las AutoConstraints para la celda xib y activar las flechas de ancho/alto flexibles en el tamaño automático para las imageviews.

 0
Author: ceekay,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-03-09 13:48:38

Estoy agregando subView y constraint programáticamente, el siguiente código funciona para mí:

lazy var imageView: UIImageView = { [unowned self] in
    let imageView = UIImageView(frame: self.contentView.frame)
    imageView.contentMode = .scaleAspectFill
    imageView.clipsToBounds = true

    return imageView
}() 

func updateCellWith(image: UIImage) {

    contentView.subviews.forEach { $0.removeFromSuperview() }

    contentView.addSubview(imageView)
    imageView.topAnchor.constraint(equalTo: contentView.topAnchor, constant: 0).isActive = true
    imageView.leftAnchor.constraint(equalTo: contentView.leftAnchor, constant: 0).isActive = true
    imageView.rightAnchor.constraint(equalTo: contentView.rightAnchor, constant: 0).isActive = true
    imageView.bottomAnchor.constraint(equalTo: contentView.bottomAnchor, constant: 0).isActive = true

    self.imageView.autoresizingMask.insert(.flexibleHeight)
    self.imageView.autoresizingMask.insert(.flexibleWidth)

    imageView.image = image

}
 0
Author: Ethandf,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-08-18 15:52:27

Yo tenía el mismo problema. Cambiar entre dos diseños no redimensionó las imágenes (UIImage) dentro de mis celdas. Mis celdas se construyen sin un xib. Y usé dos clases de celdas diferentes para cada CollectionViewCustomLayout.

Arreglé esto programáticamente con esto:

self.autoresizesSubviews = YES;

En mis subclases UICollectionViewCell.

Pero esto solo funcionó para mí al agregar la Imagen como una imagen de fondo de celdas como esta:

cell.backgroundView[[UIImageView alloc] initWithImage: SumDummyImage ];
 0
Author: Corona,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-09-16 19:06:17