UICollectionView with self-tuning cells does not calculate contentSize correctly

I have a UICollection view that works with self-calibration cells, as shown at WWDC 2014.

I want to put it in a UITableViewCell and display a tag cloud (a good link to what I want to achieve in a Foursquare app: http://i59.tinypic.com/sxd9qf.png )

My problem is that when sizing cells, the size of the content is returned incorrectly. I prepared a small demo to show the problem:

- (void)viewDidLoad { [super viewDidLoad]; self.elements = [NSMutableArray array]; for (int i = 0; i < 23; i++) { [self.elements addObject:[self randomString]]; } UICollectionViewFlowLayout* layout = [[UICollectionViewFlowLayout alloc] init]; layout.estimatedItemSize = CGSizeMake(50, 30); self.collectionView=[[UICollectionView alloc] initWithFrame:self.view.frame collectionViewLayout:layout]; [self.collectionView setDataSource:self]; [self.collectionView setDelegate:self]; UINib *cellNib = [UINib nibWithNibName:@"CustomCell" bundle:nil]; [self.collectionView registerNib:cellNib forCellWithReuseIdentifier:@"CustomCell"]; [self.collectionView setBackgroundColor:[UIColor blueColor]]; [self.view addSubview:self.collectionView]; } - (void) viewDidAppear:(BOOL)animated { [super viewDidAppear:animated]; self.collectionView.frame = CGRectMake(0, 0, self.collectionView.frame.size.width, self.collectionView.contentSize.height); } - (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section { return [self.elements count]; } - (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath { CustomCell* cell=[collectionView dequeueReusableCellWithReuseIdentifier:@"CustomCell" forIndexPath:indexPath]; cell.customLabel.text = [self.elements objectAtIndex:[indexPath row]]; return cell; } 

When I do it the old way and delete valuItemSize and instead use itemSize or delegate the method to calculate the size - it works correctly, so I think it uses the estimated size to get the size of the content.

Is there a way to make it work with self-calibration cells and authorize a UICollectionView for it?

+7
ios objective-c uicollectionview uicollectionviewlayout
source share
2 answers

I ended up calculating the size myself:

 - (CGSize) sizeForCellAtIndexPath:(NSIndexPath*) indexPath isMoreButton:(BOOL) isMoreButton { TagCell* cell = (TagCell*) [[LayoutHelper sharedLayoutHelper] collectionCellFromNib:@"TagCell"]; cell.tagLabel.text = [self.contactHashTags objectAtIndex:indexPath.row]; CGSize size = [cell systemLayoutSizeFittingSize:UILayoutFittingCompressedSize]; CGSizeMake(size.width, cell.frame.size.height); } - (CGSize) sizeForCellAtIndexPath:(NSIndexPath*) indexPath isMoreButton:(BOOL) isMoreButton { CGSize size = [self.dataSource sizeForCellAtIndexPath:indexPath isMoreButton:isMoreButton]; //limit cell to view width size.width = MIN(size.width, self.frame.size.width); return size; } 
+1
source share

My workaround ... add an insert on the fly.

 func collectionView(_ collectionView: UICollectionView, willDisplay cell: UICollectionViewCell, forItemAt indexPath: IndexPath) { let isLastItem = indexPath.item == (collectionView.numberOfItems(inSection: indexPath.section) - 1) guard isLastItem else { return } DispatchQueue.main.async { let inset = (cell.frame.maxX - collectionView.contentSize.width) + 10 // 10 is the right padding I want for my horizontal scroll collectionView.contentInset = UIEdgeInsets(top: 0.0, left: 0.0, bottom: 0.0, right: inset) } } 
+1
source share

All Articles