UICollectionView cell subviews do not resize

2019-01-06 12:13发布

In a CollectionView, some cells should have an additional subview or layer. The CollectionView can be told to resize it's cells, thus all content needs to resize appropriately.

Currently, the cell is initialized from a nib containing a cell with imageview; the cell nib is linked to a custom UICollectionViewCell subclass, that only does the init. Autoresize subviews is checked.

The CollectionView is told to resize the cell by a value derived and returned in sizeForItemAtIndexPath:. I have subclassed a FlowLayout but it only specifies ScrollDirection and Insets.

All of that is working fine. Problem: How do I add subview/layer to the cell so it also resizes correctly? I tried adding subviews and layers with translatesAutoresizingMaskIntoConstraints off, but these do not automatically change size at all. Also tried to use code frame/view instead of nib.

The best I got now is a cell.contentView.layer sublayer which I add in cellForItemAtIndexPath:; that is "manually" resized by storing the cell's frame.size from sizeForItemAtIndexPath:, which is not only ugly but also ends up with the sublayer having various sizes for different cells.

Any help appreciated!

10条回答
看我几分像从前
2楼-- · 2019-01-06 12:23

@Alfie Hanssen solution (here) didn't work properly for me, according with this article:

The size of the cell view in the XIB is 50 x 50 points, which is the default size of the collection view cells as set in the flow layout. Even if it’s a bit hard to work with a cell this small in Interface Builder, it’s better to not change the default size. The problem is that Auto Layout considers the manually set size as being fixed and generates a NSAutoresizingMaskLayoutConstraint error when it tries to adjust the cells height automatically

I have inspected the UICollectionViewCell and I found that there is a view between the cell and the contentView, and that view has intrinsic width and height constraints. Instead of the AutoresizingMask I'm just updating as below and seems working for me.

override func layoutSubviews() {
    contentView.superview?.frame = bounds
    super.layoutSubviews()
}
查看更多
Fickle 薄情
3楼-- · 2019-01-06 12:25

I had the same problem. Switching between two layouts did not resize the Pictures (UIImage) inside my cells. My Cells where build without a xib. And I used two different cell classes for each CollectionViewCustomLayout.

I fixed this programatically with this:

self.autoresizesSubviews = YES;

in my UICollectionViewCell subclasses.

But this only worked for me by adding the Picture as a cells backgroundpicture like this:

cell.backgroundView[[UIImageView alloc] initWithImage: SumDummyImage ];
查看更多
姐就是有狂的资本
4楼-- · 2019-01-06 12:30

As an alternative to enabling AutoResizingMask, for custom UICollectionViewLayouts that have variable height for example where you are setting some constraints manually and need translatesAutoresizingMaskIntoConstraints to remain NO, you can add the following to layoutSubviews in the cell:

self.contentView.frame = self.bounds;

This worked to fix all of my custom collection view layouts that had problens with Xcode 6.

查看更多
Lonely孤独者°
5楼-- · 2019-01-06 12:31

The solution was to turn off AutoConstraints for the cell xib and activate the flexible width/height arrows in the AutoResize for the imageviews.

查看更多
爷、活的狠高调
6楼-- · 2019-01-06 12:31

I'm adding subView and constraint programmatically, the following code works for me:

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

}
查看更多
唯我独甜
7楼-- · 2019-01-06 12:38

In another project without xibs i subclassed UICollectionViewCell and did this for the same effect:

#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
查看更多
登录 后发表回答