这个问题已被问过几次,但没有一个答案足够详细,我可以理解为什么/如何运作。作为参考,其他SO问题是:
How to update size of cells in UICollectionView after cell data is set?
Resize UICollectionView cells after their data has been set
Where to determine the height of a dynamically sized UICollectionViewCell?
我正在使用MVC,但为了保持简单,我可以说我有一个ViewController,它在ViewWillAppear中调用Web服务来加载一些数据。加载数据后,调用
[self.collectionView reloadData]
self.collectionView包含1个UICollectionViewCell(我们称之为DetailsCollectionViewCell)。
当创建self.collectionView时,它首先调用sizeForItemAtIndexPath然后调用cellForItemAtIndexPath。这对我来说是一个问题,因为只有在cellForItemAtIndexPath期间我通过以下方式将Web服务的结果设置为DetailsCollectionViewCell:
cell = [collectionView dequeueReusableCellWithReuseIdentifier:@"detailsCell" forIndexPath:indexPath];
((DetailsCollectionViewCell*)cell).details = result;
DetailsCollectionViewCell有一个属性详细信息的setter,它可以完成我需要先完成的一些工作,以了解正确的单元格大小应该是什么。
根据上面的链接问题,似乎是在调用cellForItemAtIndexPath之后触发sizeForItemAtIndexPath的唯一方法
[self.collectionView.collectionViewLayout invalidateLayout];
但是其他问题对我来说不起作用,因为虽然它调用sizeForItemAtIndexPath并允许我从DetailsCollectionViewCell中获取足够的信息来设置正确的高度,但在用户滚动UICollectionView和我之后才会更新UI猜测它与文档
中的这一行有关在下一个视图布局更新周期中进行实际布局更新。
然而,我很难理解如何解决这个问题。我觉得我需要在DetailsCollectionViewCell上创建一个静态方法,我可以在第一个sizeForItemAtIndexPath传递期间传递Web服务结果,然后只缓存该结果。但我希望有一个简单的解决方案让UI自动更新。
谢谢,
P.S。 - 首先提出问题,希望我能正确遵守所有规则。
答案 0 :(得分:2)
实际上,根据我的发现,调用invalidateLayout将导致在下一个单元格出列时为所有单元格调用sizeForItemAtIndexPath(这适用于iOS< 8.0,因为8.0它将在下一个视图布局更新中重新计算布局)。
所以我提出的解决方案是继承UICollectionView,并用这样的方法覆盖layoutSubviews:
- (void)layoutSubviews
{
if ( self.shouldInvalidateCollectionViewLayout ) {
[self.collectionViewLayout invalidateLayout];
self.shouldInvalidateCollectionViewLayout = NO;
} else {
[super layoutSubviews];
}
}
然后在setNeedsLayout
中调用cellForItemAtIndexPath
并将shouldInvalidateCollectionViewLayout
设置为YES。这适用于iOS> = 7.0。我也用这种方式实现了估计的项目大小。 THX。
答案 1 :(得分:0)
这是我的案例和解决方案。
我的collectionView在一个scrollView中,我希望我的collectionView和她的单元格在我滚动我的scrollView时调整大小。
所以在我的UIScrollView委托方法中:scrollViewDidScroll:
[super scrollViewDidScroll:scrollView];
if(scrollView.contentOffset.y>0){
CGRect lc_frame = picturesCollectionView.frame;
lc_frame.origin.y=scrollView.contentOffset.y/2;
picturesCollectionView.frame = lc_frame;
}
else{
CGRect lc_frame = picturesCollectionView.frame;
lc_frame.origin.y=scrollView.contentOffset.y;
lc_frame.size.height=(3*(contentScrollView.frame.size.width/4))-scrollView.contentOffset.y;
picturesCollectionView.frame = lc_frame;
picturesCollectionViewFlowLayout.itemSize = CGSizeMake(picturesCollectionView.frame.size.width, picturesCollectionView.frame.size.height);
[picturesCollectionViewFlowLayout invalidateLayout];
}
我必须重新设置collectionViewFlowLayout单元格大小然后使其布局无效。 希望它有所帮助!