带有自适应单元格的UICollectionView未正确计算contentSize

7

我正在使用WWDC 2014展示的自动调整大小单元格来工作UICollection视图。

我想将其放入UITableViewCell中,并显示标签云(实现类似Foursquare应用程序的效果,如下图所示:http://i59.tinypic.com/sxd9qf.png

我的问题是,使用自动调整大小单元格时,内容大小未正确返回。我准备了一些快速演示以展示问题:

- (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;
}

当我按照旧的方式处理,并删除estimatedItemSize并使用itemSize或委托方法计算大小时,它可以正常工作,因此我认为它是使用estimatedItem size来获取内容大小。

是否有任何方法使其与自动调整大小的单元格和根据其内容自动调整大小的UICollectionView一起工作?


2
额...我知道这并没有什么帮助,但我建议暂时不要在集合视图中使用自适应大小的单元格。似乎苹果在实现这些方面做得不是很好。https://devforums.apple.com/search.jspa?resultTypes=MESSAGE&peopleEnabled=true&q=self-sizing。 - Guillaume Algis
那么,如何按照我想要的方式实现它呢?即使进行手动计算,我仍然无法预测UICollectionView需要多少空间来显示其内容 - 我需要对UITableViewCell高度进行预测 :) - Grzegorz Krukowski
2个回答

1
我最终自己计算了大小:

- (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;
}

2
就我个人而言,在iOS 10中,我仍然遇到了自动调整大小单元格的同样问题。在下一个运行循环中,大小才是正确的。手动调整大小是唯一的解决方案。 - David Snabel-Caunt
这真的很烦人。iOS 11 的 bug 已经修复了。 - X.Y.

1
我的解决方法是...动态地添加一个插入。
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)
    }
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接