UICollectionView自动调整高度

Mar*_*ano 50 objective-c ios uicollectionview nslayoutconstraint

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

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

但这些都没有任何影响.按下按钮后,我仍然看到初始视图,如下所示:

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

我有一个小的演示程序,我有一个产生100个元素的数据源.在Interface Builder中,我最初将UICollectionView的大小设置为一个较小的值,以便不是所有元素都适合,之后我按下一个按钮,然后执行上面的代码.我希望UICollectionView现在显示所有元素,但事实并非如此.

编辑:演示程序可以在https://github.com/mjdemilliano/TestUICollectionView找到.

编辑2:我观察到帧更新在某些时候丢失,因为如果我再次按下按钮,当前帧将回到旧值.在按钮事件处理程序中添加一些日志语句后,日志输出为:

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}
Run Code Online (Sandbox Code Playgroud)

我不明白为什么不保留框架更改,改变它的原因.

在某些时候,我将用流布局中获得的值替换硬编码值,但我想排除这一点,并尽可能简单地保持我的示例.

上下文:我最终想要做的是:我有一个可滚动的视图,包含标签和图像等各种控件,以及一个包含动态内容的集合视图.我想滚动所有这些,而不仅仅是集合视图,因此我没有使用集合视图自己的滚动工具,它工作正常.

Mar*_*ano 106

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

self.verticalLayoutConstraint.constant = self.collectionView.contentSize.height;
Run Code Online (Sandbox Code Playgroud)

然后正确调整集合视图的大小,并在整个scrollview中表现良好.我已经用我的更改更新了GitHub测试项目.

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

  • 谢谢你在github上的代码,但是这个小bug.重新加载数据后,您应该设置self.verticalLayoutConstraint.constant = self.collectionView.collectionViewLayout.collectionViewContentSize.height; 而不是self.verticalLayoutConstraint.constant = self.collectionView.contentSize.height; (31认同)
  • 如何确定集合视图何时完成重新加载? (11认同)
  • 仅当您在集合视图上指定了固定宽度(通过约束)时,此方法才有效.如果使用动态宽度约束,则必须在UICollectionView知道它应该有多宽之后运行该行. (2认同)
  • "对我来说感觉不对"对我来说同样如此.但它的确有效,做得好! (2认同)

Tre*_*vor 13

它似乎与自定义 UICollectionView 类配合得很好。

class AutoSizedCollectionView: UICollectionView {

    override var contentSize: CGSize {
        didSet {
            invalidateIntrinsicContentSize()
        }
    }

    override var intrinsicContentSize: CGSize {
        layoutIfNeeded()
        return CGSize(width: UIView.noIntrinsicMetric, height: contentSize.height)
    }
}
Run Code Online (Sandbox Code Playgroud)

在界面构建器中设置您的自定义类:

在此处输入图片说明

通过这种方式,您还可以在界面构建器中将集合视图的固有大小设置为“占位符”,以避免设置高度约束。

在此处输入图片说明

我希望这对其他人有帮助。

  • 你好。我的集合视图位于 stackView 内。在这种情况下此方法不起作用。contentSize.height 始终返回 0。 (2认同)