Reputation: 481
I have a UICollectionViewCell subclass that contains 2 UILabels (titleLable, subtitleLabel). I have the constraints setup so that both labels can grow depending on the size of the text, however at run time the subtitleLabel always cuts one entire line off. I'm pretty new to Autolayout so I'd appreciate any advice.
Also, my collectionView layout is meant to emulate a UITableView, so using UITableView instead wouldn't be a valid solution for me. Thanks.
Here's the setup:
UICollectionViewCell subclass:
- (instancetype)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
if (self) {
UILabel *titleLabel = [[UILabel alloc] initWithFrame:CGRectZero];
titleLabel.translatesAutoresizingMaskIntoConstraints = NO;
titleLabel.lineBreakMode = NSLineBreakByWordWrapping;
titleLabel.numberOfLines = 0;
[self.contentView addSubview:titleLabel];
_titleLabel = titleLabel;
UILabel *subtitleLabel = [[UILabel alloc] initWithFrame:CGRectZero];
subtitleLabel.translatesAutoresizingMaskIntoConstraints = NO;
subtitleLabel.lineBreakMode = NSLineBreakByWordWrapping;
subtitleLabel.numberOfLines = 0;
[self.contentView addSubview:subtitleLabel];
_subtitleLabel = subtitleLabel;
_contentInsets = UIEdgeInsetsZero;
}
return self;
}
- (void)updateConstraints
{
NSDictionary *metrics = self.metricsDictionary;
NSDictionary *views = self.viewsDictionary;
[self.contentView addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:|-leftInset-[_titleLabel]-rightInset-|" options:0 metrics:metrics views:views]];
[self.contentView addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:|-topInset-[_titleLabel]-[_subtitleLabel]-bottomInset-|" options:NSLayoutFormatAlignAllLeft | NSLayoutFormatAlignAllRight metrics:metrics views:views]];
[super updateConstraints];
}
UICollectionViewDataSource:
- (CGSize)collectionView:(UICollectionView *)collectionView sizeForItemAtIndexPath:(NSIndexPath *)indexPath
{
if (!self.prototypeCell) {
self.prototypeCell = [[FLCollectionViewCell alloc] initWithFrame:CGRectZero];
[self.prototypeCell updateConstraints];
}
self.prototypeCell.contentView.bounds = CGRectMake(0, 0, CGRectGetWidth(collectionView.bounds)/self.defaultMetrics.numberOfColumns, 99999);
[self updateCollectionView:collectionView cell:self.prototypeCell atIndexPath:indexPath];
CGSize size = [self.prototypeCell.contentView systemLayoutSizeFittingSize:UILayoutFittingCompressedSize];
return CGSizeMake(size.width, size.height);
}
- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath
{
FLCollectionViewCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:kFLProjectCompanyCellReuseIdentifier forIndexPath:indexPath];
[self updateCollectionView:collectionView cell:cell atIndexPath:indexPath];
return cell;
}
- (void)updateCollectionView:(UICollectionView *)collectionView cell:(FLCollectionViewCell *)cell atIndexPath:(NSIndexPath *)indexPath
{
NSMananagedObject *model = [self itemAtIndexPath:indexPath];
cell.preferredMaxLayoutWidth = CGRectGetWidth(collectionView.bounds); // This just sets the preferredMaxLayoutWidth for the cell's titleLabel and subtitleLabel
cell.titleLabel.text = model.title;
cell.subtitleLabel.text = model.subtitle;
[cell layoutIfNeeded];
}
My results look like this:
The subtitle for every cell is one line short, which is most apparent in the last cell which contains one line, but the frame has no height.
Upvotes: 0
Views: 2414
Reputation: 481
Derp! Figured this out. The prototype cell I was allocating to determine the size for the cell was not taking into account the contentInsets
(UIEdgeInsets) that were being applied to the cell by custom subclass of UICollectionViewLayoutAttributes
in the applyLayoutAttributes:
method.
The UICollectionView
method dequeueReusableCellWithReuseIdentifier:forIndexPath:
automatically runs the UICollectionViewCell
method applyLayoutAttributes:
. However, when determining the size of the cell I use initWithFrame: because the collectionView
method will forward a prepareLayout
call back to the UICollectionView layout
instance, which is where I'm trying to determine the size of the cell anyway.
Sooooo long story short, I just set the contentInsets on the prototypeCell
directly and now my height is correct!
Upvotes: 1