web-dev-qa-db-fra.com

Les sous-vues de cellules UICollectionView ne sont pas redimensionnées

Dans une CollectionView, certaines cellules devraient avoir une sous-vue ou couche supplémentaire. On peut dire à CollectionView de redimensionner ses cellules, ainsi tout le contenu doit être redimensionné correctement.

Actuellement, la cellule est initialisée à partir d'une nib contenant une cellule avec imageview; la nib de cellule est liée à une sous-classe UICollectionViewCell personnalisée, qui ne fait que l'init. Le redimensionnement automatique des sous-vues est coché.

Il est dit à CollectionView de redimensionner la cellule par une valeur dérivée et renvoyée dans sizeForItemAtIndexPath:. J'ai sous-classé un FlowLayout mais il ne spécifie que ScrollDirection et Insets.

Tout cela fonctionne bien. Problème: Comment puis-je ajouter une sous-vue/couche à la cellule pour qu'elle soit également redimensionnée correctement? J'ai essayé d'ajouter des sous-vues et des couches avec l'option translatesAutoresizingMaskIntoConstraints off, mais celles-ci ne changent pas automatiquement de taille. A également essayé d'utiliser le code frame/view au lieu de nib. 

Le meilleur que j'ai maintenant est une sous-couche cell.contentView.layer que j'ajoute dans cellForItemAtIndexPath:; qui est redimensionné "manuellement" en stockant le frame.size de la cellule à partir de sizeForItemAtIndexPath:, ce qui est non seulement moche mais aboutit également à une sous-couche de tailles différentes pour différentes cellules.

Toute aide appréciée!

36
ceekay

La solution consistait à désactiver les contraintes automatiques pour la cellule xib et à activer les flèches de largeur/hauteur flexibles dans la taille automatique pour les vues d'image.

0
ceekay

J'ai rencontré le même problème tout à l'heure. 

Lorsque vous utilisez la méthode UICollectionViewFlowLayoutDelegate pour définir la taille de la cellule en fonction du périphérique et de l'orientation du périphérique, la taille est calculée correctement mais les sous-vues ne sont pas redimensionnées pour remplir la nouvelle cellule. L'effet était une grande cellule vide avec de petites sous-vues qui ne remplissaient pas les limites de la cellule/restaient la taille égale à leur valeur actuelle dans le fichier xib. 

J'ai résolu ce problème en procédant comme suit dans awakeFromNib

- (void)awakeFromNib
{
    [super awakeFromNib];

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

Auparavant, le masque contentView était nil.

83
Alfie Hanssen
*override func awakeFromNib() {
    super.awakeFromNib()

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

Cela a fonctionné pour moi .. Ce code se trouve à l'intérieur de votre fichier UICollectionViewCell.Swift de la sous-classe (où se trouve votre code impliquant la cellule personnalisée).

Solution rapide *

17
NSCoyote

En guise d'alternative à l'activation d'AutoResizingMask, pour les UICollectionViewLayouts personnalisés ayant une hauteur variable, par exemple, lorsque vous définissez certaines contraintes manuellement et que vous devez activer la traduction deAutoresizingMaskIntoConstraints, vous pouvez ajouter les éléments suivants à layoutSubviews dans la cellule:

self.contentView.frame = self.bounds;

Cela a permis de corriger toutes les dispositions de vue de ma collection personnalisée posant des problèmes avec Xcode 6.

6

Dans un autre projet sans xibs, j'ai sous-classé UICollectionViewCell et je l'ai fait pour le même effet:

#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
ceekay

Je préfère toujours l'autolayout dans la mesure du possible ... Mais, parfois, utiliser des cadres et des limites représente un gain de temps considérable lorsqu'une vue est déterminée directement par son aperçu.

Dans le cas de UICollectionViewCell, j'ai défini une image comme étant le cadre de cellules + self.imageView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;

Mais quand j'avais différentes tailles de cellules dans la collection, les choses se gâtaient et l'image prenait parfois la taille d'une cellule différente.

Je me suis donc tourné vers le travail dans les limites des cellules et - vous avez très bien fonctionné.

Alors peut-être essayer?

3
Pedroinpeace

Une solution de mise en page automatique simple consiste à définir des contraintes pour la vue conteneur.

Ainsi, si nous avons une vue d'image avec une vue parent, nous voulons essentiellement indiquer à la sous-vue (la vue d'image) de conserver une distance d'espacement avant, arrière, inférieure et supérieure de 0 par rapport à la vue conteneur.

Auto layout constraints to resize with parent view

3
jlmendezbonini

La solution @Alfie Hanssen ( ici ) n'a pas fonctionné correctement pour moi, selon cet article :

La taille de la vue de cellule dans le fichier XIB est de 50 x 50 points, ce qui correspond à la taille par défaut des cellules de la vue de collection définie dans la présentation du flux. Même s'il est un peu difficile de travailler avec une cellule aussi petite dans Interface Builder, il est préférable de ne pas modifier la taille par défaut. Le problème est que la disposition automatique considère la taille définie manuellement comme étant corrigée et génère une erreur NSAutoresizingMaskLayoutConstraint lorsqu'il tente d'ajuster automatiquement la hauteur des cellules

J'ai inspecté UICollectionViewCell et j'ai constaté qu'il y avait une vue entre la cellule et contentView, et que cette vue avait des contraintes intrinsèques de largeur et de hauteur. Au lieu de AutoresizingMask, je ne fais que mettre à jour comme ci-dessous et semble fonctionner pour moi. 

override func layoutSubviews() {
    contentView.superview?.frame = bounds
    super.layoutSubviews()
}
2
Serluca

J'ai eu le même problème. La commutation entre deux présentations ne redimensionnait pas les images (UIImage) dans mes cellules. Mes cellules ont été construites sans xib. Et j'ai utilisé deux classes de cellules différentes pour chaque CollectionViewCustomLayout.

J'ai corrigé cela par programmation avec ceci:

self.autoresizesSubviews = YES;

dans mes sous-classes UICollectionViewCell.

Mais cela n’a fonctionné que pour moi en ajoutant l’image en tant que cellule backgroundpicture comme ceci:

cell.backgroundView[[UIImageView alloc] initWithImage: SumDummyImage ];
0
Corona

J'ajoute subView et constraint par programme, le code suivant fonctionne pour moi: 

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
Ethandf