UICollectionView自动调整高度

如何正确调整UICollectionView的大小,使其完全显示其内容? 我尝试了很多东西,包括设置框架,调用reloadData并使布局无效:

 self.collectionView.contentSize = CGSizeMake(300, 2000); self.collectionView.frame = CGRectMake(0, 0, 300, 2000); [self.collectionView reloadData]; [self.collectionView.collectionViewLayout invalidateLayout]; 

但没有任何影响。 按下button后,我仍然可以看到初始视图,如下所示:

集合视图仅显示帧大小调整后的部分内容

我有一个小的演示程序,我有一个数据源生成100个元素。 在界面生成器中,我最初将UICollectionView的大小设置为一个小值,以便不是所有元素都适合,之后我按下一个button,之后执行上面的代码。 我期望UICollectionView现在显示所有元素,但它不。

编辑:演示程序可以在https://github.com/mjdemilliano/TestUICollectionViewfind。

编辑2:我已经观察到帧更新在某个点丢失,因为如果我再次按下button,当前帧返回到旧值。 在button事件处理程序中添加一些日志语句之后,日志输出为:

 before: frame = {{0, 58}, {320, 331}}, contentSize = {320, 1190} update button pressed after: frame = {{0, 0}, {300, 2000}}, contentSize = {300, 2000} before: frame = {{0, 58}, {320, 331}}, contentSize = {320, 1190} update button pressed after: frame = {{0, 0}, {300, 2000}}, contentSize = {300, 2000} 

我不明白为什么不改变框架,改变它。

在某些时候,我会用从stream布局中获得的值来replace硬编码值,但是我想排除这个问题,并尽可能简化我的示例。

上下文:我想要做的最终是以下几点:我有一个可滚动的视图与各种控件,如标签和图像,以及与dynamic内容的集合视图。 我想滚动所有,而不仅仅是集合视图,因此我没有使用收集视图自己的滚动设施,工作正常。

我最终通过修复所有自动布局问题解决了这个问题,使用约束来固定集合视图的高度。 然后,每当我知道内容已经改变,我使用值collectionView.contentSize.height更新约束的值:

 self.verticalLayoutConstraint.constant = self.collectionView.contentSize.height; 

然后收集视图正确调整,并在整个滚动视图内很好地行事。 我已经更新了GitHubtesting项目。

对我来说,通过手动更新约束来做到这一点,而不是能够告诉iOS:“使集合视图的帧高度尽可能大”对我来说并不合适,但这是迄今为止我所得到的最好的。 如果你有一个,请发布一个更好的答案。

这是我在Swift 3中的实现:

 override func sizeThatFits(_ size: CGSize) -> CGSize { if (self.superview != nil) { self.superview?.layoutIfNeeded() } return collectionView.contentSize } 
 UICollectionViewFlowLayout *flowLayout; flowLayout = [[UICollectionViewFlowLayout alloc]init]; [flowLayout setScrollDirection:UICollectionViewScrollDirectionVertical]; [flowLayout setMinimumInteritemSpacing:0.0f]; [flowLayout setMinimumLineSpacing:0.0f]; [self.collectionView setPagingEnabled:NO]; [flowLayout setItemSize:CGSizeMake(322.0, 148.0)]; //important to leave no white space between the images [self.collectionView setCollectionViewLayout:flowLayout]; 

我发现故事板中的自动布局不是太有帮助。 UICollectionViewFlowLayout为您的collectionView正确的设置是真正的帮助。 如果使用setItemSize调整项目大小,则可能会得到所需的结果。

这是一种通过内在大小绑定CollectionView高度的方法。 我用它来正确地调整一个TableView单元格内的CollectionView(dynamic单元格的高度)。 它完美的作品。

首先,将此添加到您的UICollectionView子类:

 override var intrinsicContentSize: CGSize { get { return self.contentSize } } 

然后在重载数据之后调用layoutIfNeeded():

 reloadData() layoutIfNeeded() 

我发现最简单的方法是pverride sizeThatFits:方法是这样的:

 - (CGSize)sizeThatFits:(CGSize)size { if( self.superview ) [self.superview layoutIfNeeded]; // to force evaluate the real layout return self.collectionViewLayout.collectionViewContentSize; } 

对我来说,我觉得更简单

 -(UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath { //add following code line after adding cells, before Return ........... ......... scrollView.contentSize = = collectionView.contentSize; //now scrollView size is equal to collectionView size. No matter how small or big it is. return cell; }