ios - tutorial - uicollectionviewdatasource
UICollectionView con células auto-dimensionadas que no calculan contentSize correctamente (2)
Tengo la vista UICollection trabajando con celdas de auto-tamaño como se muestra en WWDC 2014.
Quiero ponerlo dentro de UITableViewCell y mostrar una nube de etiquetas (una buena referencia de lo que quiero lograr es en la aplicación Foursquare: )
Mi problema es que con las celdas de tamaño propio, el tamaño del contenido no se devuelve correctamente. Preparé una demostración rápida para mostrar el problema:
- (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;
}
Cuando lo hago de manera antigua y elimino estimateItemSize y uso itemSize en su lugar o delegar el método para calcular un tamaño, funciona correctamente, así que creo que está usando el tamaño del tamaño estimado para obtener el tamaño del contenido.
¿Hay alguna forma de hacerlo funcionar con celdas de autoevaluación y de convertir automáticamente UICollectionView a su contenido?
Terminé calculando el tamaño por mi cuenta:
- (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;
}
Mi solución ... agregar un recuadro sobre la marcha.
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)
}
}