UICollectionView 布局问题

63

我正在使用基于流布局的 UICollectionView,并为其创建了自定义的 UICollectionViewCell。但在运行项目时,控制台不断抛出此错误:

The behavior of the UICollectionViewFlowLayout is not defined because:
 the item height must be less that the height of the UICollectionView minus the section insets top and bottom values.

我已确保单元格的大小正确。

有没有人能够解决这个问题。


请添加有关flowLayout.itemSize、collectionView.frame的信息!旋转或viewDidLoad时崩溃? - Alex
11
我发现只有当我将滚动方向选择为水平时才会出现这个错误。 - Nitesh
1
它不会崩溃,只是用户界面变空白了。 这是单元格的大小。300X460 集合视图框架-300X480 布局框架-300X480 我从xib中获取了所有这些值。 我希望集合视图可以水平滚动而不是垂直滚动。 - Nitesh
itemSize应该小于CollectionView的高度或宽度,请检查您的itemSize和CollectionView.frame。 - Alex
是因为我将滚动设置为水平方向吗?因为在垂直滚动时似乎运行良好。 - Nitesh
本帖解释了为什么会发生这种情况,并提供了解决方案: https://dev59.com/nVwY5IYBdhLWcg3w5bTt#39497850 - ElectroBuddha
16个回答

39

我发现,使用storyboards时,你需要进入storyboard并点击整个View Controller(视图应该被突出显示为蓝色),然后进入属性检查器(屏幕右侧的第四个选项卡)并取消选中 "Under Top Bars"、 "Under Bottom Bars" 和 "Under Opaque Bars"。这样可以解决我的问题,也可以解决我的同事的问题。


3
我发现取消选中“Adjust Scroll View Insets”可以删除警告。(在使用Storyboards和单元格自动布局时) - Jason Moore
谢谢伙计!你刚刚救了我的命!它对我起作用了。 - Muhammad Sarim
对我有用:在基于Storyboard的UIView上编程添加了CollectionView。 - lal

29

当我使用collection view来展示全屏视图控制器时,遇到了一些问题。

基本上在运行时,它会请求该项的大小并简单地返回collection view的大小:

-(CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout *)collectionViewLayout sizeForItemAtIndexPath:(NSIndexPath *)indexPath {
    return self.collectionView.frame.size;
}

4
如果您想支持旋转,这比我的答案更好。 - Jonathan Crooke

28

我知道这是一个非常晚的回复,但我也遇到了这个问题。

在我的视图控制器中,我们称之为MyViewController,我有一个使用自定义UICollectionViewCellUICollectionView。我实现了方法collectionView:layout:sizeForItemAtIndexPath,在其中返回一个取决于UICollectionView高度的项目大小。

MyViewController是用自动布局制作的故事板来控制UIViewController的高度。

当处于竖屏模式时,单元格看起来很好,但是当处于横屏模式时,它们就不行了。

我通过在viewWillLayoutSubviews 方法中使无效化UICollectionViewLayout来解决我的问题。

- (void)viewWillLayoutSubviews {
    [self.myCollectionView.collectionViewLayout invalidateLayout];
}

早些时候,我曾试图在 willAnimateRotationToInterfaceOrientation:duration 方法内部使布局无效化,但是这并没有起作用。这个问题的原因可能是所有视图的尺寸还没有计算出来,所以我们必须等待自动布局完成其魔法。我参考了 这个SO线程

更新Swift 4.0版:

  override func viewDidLayoutSubviews() {
    super.viewDidLayoutSubviews()
    self.myCollectionView.collectionViewLayout.invalidateLayout()
  }

经过数小时尝试不同的建议后,这个简单的解决方案消除了我的布局警告。谢谢! - iksnae
这对我在一个UIView内的collectionView起作用。我已经花了几个小时在这个问题上,这是唯一有效的解决方法!我只是重写了layoutSubviews方法。 - Dominic Holmes

18

在尝试创建全屏单元格的集合视图时,我自己也遇到了几次这个问题。我的问题是在IB/Storyboard中为4英寸屏幕布局并指定320 * 568的项大小,但在模拟器上运行时使用3.5英寸屏幕,其高度为480。解决方案是使用类似以下代码的方式在代码中指定您的项大小:

UICollectionViewFlowLayout *layout = (id) self.collectionView.collectionViewLayout;
layout.itemSize = self.collectionView.frame.size;

这确保了单元格大小在运行时正确设置。

2
为什么将整个视图的尺寸分配给单个单元格的尺寸? - expert
1
我在全屏单元格中遇到了这个问题。不确定原帖作者是否也是同样的情况,但这是你可能会遇到这个问题的最明显的方式。 - Jonathan Crooke

10

如果您正在使用故事板和自动布局,则调试此类问题确实很困难...

当我尝试在iPhone上全屏显示UICollectionViewCell时,我遇到了类似的问题。

大多数情况下问题出在单元格大小设置上。

-(CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout *)collectionViewLayout sizeForItemAtIndexPath:(NSIndexPath *)

或者直接在flowLayout.itemSize上进行尝试。

  1. 选择视图控制器:

选择视图控制器

  1. 然后取消“扩展边缘”选项:

禁用扩展边缘选项

现在可以尝试设置自动布局约束了。

祝好运。


3
这解决了我的问题:
-(CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout*)collectionViewLayout sizeForItemAtIndexPath:(NSIndexPath *)indexPath 
{ 
return CGSizeMake(self.collectionView.frame.size.width, self.collectionView.frame.size.height - 70);
}

您可以在此屏幕上看到从顶部和底部的填充值:

输入图像描述


2
对于我而言,我在一个自定义的UIView中使用了AKPickerView,这给我带来了一堆警告,就像这里提到的那样。为了消除这些警告,我所做的就是在我的自定义UIView的属性检查器中取消勾选名为“自动调整子视图大小”的选项。这使得警告消失得如此之彻底,以至于我以为我的日志记录器停止工作了。

enter image description here


2

一定要为UICollectionView和UICollectionviewcell设置正确的自动调整大小掩码。这解决了我在iPhone 4模拟器上的问题。


此外,在单元格的contentView(或UITableViewCell的content view)上设置自动调整大小掩码也可以帮助。 - Arie Litovsky

2
我遇到的问题是,我试图将我的单元格大小设置为父视图的大小而不是UICollectionView的大小。只需使用UICollectionView框架替换父视图框架即可解决此问题。

我之前在使用 CGSize(width: view.frame.width, height:view.frame.height) 作为集合视图单元格的大小,后来我改成了 CGSize(width: collectionView.frame.width, height: collectionView.frame.height),现在一切都正常了。(我将一个集合视图放在另一个集合视图单元格中) - Richard Mao

2

我在collectionView中需要全屏的单元格时遇到了这个问题。所以我用以下方法解决了这个问题。

  1. 单元格大小等于collectionView大小

enter image description here 2. 在Storyboard中将"Inset from:"从安全区域改为内容插图

enter image description here

  1. 将"Content Insets"更改为Never enter image description here

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