By ceekay


2013-03-08 20:54:19 8 Comments

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 comments

@Corona 2014-01-23 18:39:52

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 ];

@ceekay 2014-01-25 20:16:21

Subclassing works similar, see below

@Ethandf 2017-08-18 15:52:27

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

}

@Serluca 2016-06-03 10:10:33

@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()
}

@NSCoyote 2016-03-24 22:23:07

*override func awakeFromNib() {
    super.awakeFromNib()

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

This worked for me.. This code goes inside of your subclassed UICollectionViewCell.swift file (where your code involving the custom cell is located)

Swift solution*

@denis631 2017-09-23 09:18:03

how could I forget this... Thanks!

@Praneeth Wanigasekera 2014-09-23 06:26:50

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.

@Mazyod 2014-10-19 07:17:50

+1 this worked for me, but there is really no need for the redundant CGRectInset

@Praneeth Wanigasekera 2014-10-28 02:37:49

Thanks. Removed.

@Alfie Hanssen 2014-09-10 20:26:25

I ran into the same issue just now.

When using the UICollectionViewFlowLayoutDelegate method to set the cell size depending on device and device-orientation, the size would be calculated properly but subviews would not resize to fill the newly size cell. The effect was a large blank cell with small subviews that don't fill the cell's bounds / remain the size equal to their current value in the xib file.

I solved this by doing the following in awakeFromNib:

- (void)awakeFromNib
{
    [super awakeFromNib];

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

Prior to doing this, the contentView mask was nil.

@Vincent Saluzzo 2014-09-12 10:00:43

Thanks @alfie-hanssen , your solution help to resolve a bug when switching from Xcode5 to Xcode6 with custom UICollectionViewLayout

@Alfie Hanssen 2014-09-12 14:37:57

Thanks, glad it helped!

@Xyand 2014-09-14 07:15:59

This one is simple and actually works!

@Arman 2014-09-16 20:39:30

Thank you. This problem appeared on iOS 7 devices once I started building with Xcode 6 GM, and adding this to all my collection cell subclasses fixed it.

@Alexander Tkachenko 2014-09-18 11:41:26

Thank you, Alfie! The same problem with iOS 7 devices when I started building with XCode 6 GM.

@warpedspeed 2014-09-18 18:33:20

Worked for me as well.

@ikzjfr0 2014-10-02 02:09:47

Same thing happens here and you save my life. By the way, is it a bug of iOS or what's the root cause for this?

@Jono 2014-10-06 00:21:06

Wow, there's no way I would have figured this out. I could not get a label to span the full width of a collectionView cell in Xcode 6 with the iOS7 sim. It worked fine in the iOS8 sim. I added the above awakeFromNib function to my collectionView cell subclass (which was otherwise almost completely empty) and now both the iOS7 and iOS 8 simulators properly layout the cell views. Huge thanks!

@Joey 2014-10-22 02:52:50

It seems to be fixed on Xcode 6.1

@Pangu 2015-01-30 04:17:17

thanks so much alfie, I was getting constraints conflicts until your code fixed it!

@Blip 2015-06-26 19:42:22

Here's a link to another answer on the same problem: stackoverflow.com/a/25768887/2631081

@lobodart 2015-07-10 09:06:08

Should be the accepted answer ! You saved me working hours !!

@Cal S 2015-09-22 09:31:12

Fixed an issue migrating from Xcode 6 (iOS 7) to 7 (iOS 9).

@abhimuralidharan 2015-11-30 10:10:09

Thanks man..this should be the accepted answer

@S At 2017-12-05 09:11:14

How to do with swift 4

@jlmendezbonini 2014-04-15 00:01:04

A simple auto layout solution is to set constraints to the container view.

So if we have an image view with a parent view, we basically want to tell the subview (the image view) to maintain a leading, trailing, bottom, and top space distance of 0 to the container view.

Auto layout constraints to resize with parent view

@Matt 2014-10-14 03:10:19

Didn't work for me. iOS 7, XCode 6.

@Coder221 2016-09-19 07:44:29

Best solution ever. Works for iOS 9.3, Xcode 8.

@Pedroinpeace 2014-03-06 09:59:14

I always prefer autolayout when possible. But Sometimes usings frames and bounds just is a timesaver when a view is determined straightforward by only its superview.

In the case of UICollectionViewCell I set an image to be the cells frame + self.imageView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;

But when I had different sizes of cells in the collectionView it messed up things and the image sometimes took the size of a different cell.

So I turned to working with the the cells bounds and - ye that acually worked out fine.

So maybe give that a try?

@Wraithseeker 2015-07-10 17:49:00

by setting autoresizing mask it worked great!

@ceekay 2014-01-25 20:20:16

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

@Hari Karam Singh 2014-07-29 16:18:08

Doesn't setting translatesAutoresizingMaskIntoConstraints to NO mean that it will ignore the autoresizingMask? I'm under the impression that under-the-hood there is no such thing at non-autolayout, just autolayout which mimics the old/alternative way.

@ceekay 2013-03-09 13:48:38

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

@Mansuu.... 2017-07-13 11:18:17

Turning off he constraints causes misplacement of xib file subviews

Related Questions

Sponsored Content

26 Answered Questions

15 Answered Questions

[SOLVED] Remove all subviews?

  • 2010-01-28 16:20:00
  • BahaiResearch.com
  • 163882 View
  • 311 Score
  • 15 Answer
  • Tags:   ios subview

5 Answered Questions

[SOLVED] UICollectionView + SDWebImage + Cell reuse

3 Answered Questions

0 Answered Questions

Reordering cell interactively with resized imageView

1 Answered Questions

2 Answered Questions

1 Answered Questions

0 Answered Questions

UICollectionViewCell disappears after reloadData

Sponsored Content