24

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

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

collectionView.collectionViewLayout.collectionViewContentSize

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

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

4

4 回答 4

6

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

于 2014-07-04T13:23:24.650 回答
6

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

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

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

如果我理解正确的话。

于 2013-06-09T20:06:47.160 回答
0

更改 UICollectionView 框架的步骤:

  1. 将collectioview的超级视图的“translatesAutoresizingMaskIntoConstraints”属性设置为YES(如果您使用的是AUTOLAYOUT)

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

    collectionView.frame = CGRectMake (x,y,w,h);
    [collectionView reloadData];
    
于 2016-04-25T10:02:19.360 回答
0

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

我在以下代码中使用 SnapKit。

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

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

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

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

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)
}

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

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

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

于 2018-09-07T18:53:01.350 回答