Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Auto Layout: can't get the frame size of UICollectionViewCell subViews

I have a custom UICollectionViewCell subclass (MyCell), its interface is setup in Interface Builder using Auto Layout. The cell has an image view and a label.

Now, when I configure the cell, I need to know the width and the height of the image view. Sounds pretty simple, but it looks like it's impossible.

In my view controller:

- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath {
    MyCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:@"MyCell" forIndexPath:indexPath];
    cell.itemNumber = indexPath.item;
    return cell;
}

In my cell subclass I am using my property's setter to customize the cell:

- (void)setItemNumber:(NSInteger)itemNumber {
    _itemNumber = itemNumber;
    self.label.text = [NSString stringWithFormat:@"%i", self.itemNumber];

    // In my actual project I need to know the image view's width and hight to request an image
    // of the right size from a server. Sadly, the frame is always {{0, 0}, {0, 0}}
    // (same for the bounds)
    NSLog(@"%@", NSStringFromCGRect(self.myImageView.frame));
}

A full example project can be found at https://github.com/kevinrenskers/CollectionViewAutoLayoutTest.

So the problem is this: I need to know the image view's size because I need to ask a server to generate an image of the correct size. And the image view's size is {0,0}..

I've tried to do the customizing in the -layoutSubviews method too:

- (void)setItemNumber:(NSInteger)itemNumber {
    _itemNumber = itemNumber;
}

- (void)layoutSubviews {
    if (self.myImageView.frame.size.height) {
        self.label.text = [NSString stringWithFormat:@"%i", self.itemNumber];
        NSLog(@"%@", NSStringFromCGRect(self.myImageView.frame));
    }
}

Sadly, this is even more messed up. The method is called twice, first the frame is {{0, 0}, {0, 0}} and then the frame is set correctly. Thus the if statement that checks for the height. Once you start scrolling though, the wrong labels are showed for the wrong cells. I don't understand what's going on here.

The problem probably makes more sense when you try it in the example project.

Setting width- and height constraints and making IBOutlets to it sounds like a great option, but sadly the cells don't have a fixed size and the image needs to shrink and grow with the cell. Removing auto layout isn't an option either.

like image 320
Kevin Renskers Avatar asked Nov 12 '22 00:11

Kevin Renskers


1 Answers

In the end I added top, right, bottom and left spacing constraints on the imageview (to the superview), added IBOutlets to them and used something like this:

CGFloat height = self.contentView.bounds.size.height - self.topConstraint.constant - self.bottomConstraint.constant;
CGFloat width = self.contentView.bounds.size.width - self.leftConstraint.constant - self.rightConstraint.constant;
like image 144
Kevin Renskers Avatar answered Nov 15 '22 07:11

Kevin Renskers