ios 自动调整 UICollectionView 高度以适应其内容大小

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/17012397/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-30 23:51:08  来源:igfitidea点击:

Autoresize UICollectionView height to adjust to its content size

iosuicollectionview

提问by AVokin

I have a UICollectionView, a button that creates a new cell in collection view. And I want UICollectionView to adjust it's size according to it's content size (when there are one or two cells then UICollectionView is short, if there are a lot of cell UICollectionView is big enough).

我有一个 UICollectionView,一个在集合视图中创建新单元格的按钮。我希望 UICollectionView 根据它的内容大小调整它的大小(当有一个或两个单元格时 UICollectionView 很短,如果有很多单元格 UICollectionView 足够大)。

I know how to get content size:

我知道如何获取内容大小:

collectionView.collectionViewLayout.collectionViewContentSize

collectionView.collectionViewLayout.collectionViewContentSize

But I have no idea where to use this value. I would appreciate if somebody help me to figure out how to make UICollectionView auto adjust it's height.

但我不知道在哪里使用这个值。如果有人帮我弄清楚如何让 UICollectionView 自动调整它的高度,我将不胜感激。

UPD: I published on GitHub a demo project that describes the problem: https://github.com/avokin/PostViewer

UPD:我在 GitHub 上发布了一个描述问题的演示项目:https: //github.com/avokin/PostViewer

采纳答案by RegularExpression

I don't think content size is what you're after. I think you're wanting to adjust the amount of screen real estate consumed by the collection view, right? That's going to require adjustment of the frame. The content size includes the off-screen (scrolling) area as well as the on screen view.

我不认为内容大小是你所追求的。我认为您想要调整集合视图消耗的屏幕空间量,对吗?这将需要调整框架。内容大小包括屏幕外(滚动)区域以及屏幕视图。

I don't know of anything that would prevent you from just changing the frame size on the fly:

我不知道有什么会阻止您即时更改帧大小:

collectionView.frame = CGRectMake (x,y,w,h);
[collectionView reloadData];

If I'm understanding you correctly.

如果我理解正确的话。

回答by sammalfix

Use a height constraint for the collection view and update its value with the content height when needed. See this answer: https://stackoverflow.com/a/20829728/3414722

对集合视图使用高度约束,并在需要时使用内容高度更新其值。看到这个答案:https: //stackoverflow.com/a/20829728/3414722

回答by Shahul Hasan

Steps to change the UICollectionView frame:

更改 UICollectionView 框架的步骤:

  1. Set the "translatesAutoresizingMaskIntoConstraints" property to YES for the collectioview's superview (If you are using AUTOLAYOUT)

  2. Then update the collectioview's frame as :

    collectionView.frame = CGRectMake (x,y,w,h);
    [collectionView reloadData];
    
  1. 将collectioview的超级视图的“translatesAutoresizingMaskIntoConstraints”属性设置为YES(如果您使用的是AUTOLAYOUT)

  2. 然后将collectioview的框架更新为:

    collectionView.frame = CGRectMake (x,y,w,h);
    [collectionView reloadData];
    

回答by emp

You need to constrain the collection view height to the height of your content:

您需要将集合视图高度限制为内容的高度:

I'm using SnapKit in the following code.

我在以下代码中使用 SnapKit。

First constrain the collection view edges to its superview:

首先将集合视图边缘约束到其超视图:

private func constrainViews() {
    collectionView?.translatesAutoresizingMaskIntoConstraints = true

    collectionView?.snp.makeConstraints { make in
        make.edges.equalToSuperview()
        heightConstraint = make.height.equalTo(0).constraint
    }
}

Next calculate the height and set the height to the height constraint offset. I'm letting the flow layout do the work, and then calculating the height based on the bottom edge of the last layout attribute:

接下来计算高度并将高度设置为高度约束偏移量。我让流布局完成工作,然后根据最后一个布局属性的底部边缘计算高度:

override func viewDidLayoutSubviews() {
    guard
        let collectionView = collectionView,
        let layout = collectionViewLayout as? UICollectionViewFlowLayout
    else {
        return
    }

    let sectionInset = layout.sectionInset
    let contentInset = collectionView.contentInset

    let indexPath = IndexPath(item: tags.count, section: 0)
    guard let attr = collectionViewLayout.layoutAttributesForItem(at: indexPath) else {
        return
    }

    // Note sectionInset.top is already included in the frame's origin
    let totalHeight = attr.frame.origin.y + attr.frame.size.height
        + contentInset.top + contentInset.bottom
        + sectionInset.bottom

    heightConstraint?.update(offset: totalHeight)
}

Note that in the example, I always have one special tag not included in my items tagscount, so the line:

请注意,在示例中,我总是有一个特殊标签不包含在我的项目tags计数中,因此该行:

let indexPath = IndexPath(item: tags.count, section: 0)

would need to be something like if items.count > 0 ... let indexPath = IndexPath(item: tags.count - 1, section: 0)in most other code.

需要类似于if items.count > 0 ... let indexPath = IndexPath(item: tags.count - 1, section: 0)大多数其他代码。