分组的 UICollectionView 有额外的 35 像素顶部填充

Grouped UICollectionView has extra 35 pixels of top padding

我正在创建一个 grouped UICollectionView,顶部似乎有 35 像素的额外填充,我不知道如何去掉。

这似乎也是 UITableView 的问题,我发现了一些问题来解决它 here and here,但这些解决方案不适用于 UICollectionView

下面是我如何初始化 UICollectionView:

var listConfig = UICollectionLayoutListConfiguration(appearance: .grouped)
UICollectionView(frame: .zero, collectionViewLayout: UICollectionViewCompositionalLayout.list(using: listConfig))
// More autolayout constraints code later

到目前为止,为了解决这个问题,我一直在对 topAnchor 应用一个 -35 常量,但这并不适用于所有情况(当我想要在同一视图的正上方的某些内容时)。

我也试过listConfig.headerTopPadding = 0没有成功。

我怎样才能摆脱这个额外的顶部填充? (附带问题......为什么存在?)

在我写这个问题的时候,我又发现了一个 ,它最终给了我一个对我有用的答案。我使用了方法4:

collectionView.contentInset = UIEdgeInsets(top: -35, left: 0, bottom: 0, right: 0)

这会向上移动我的内容,并允许我毫无问题地将内容放在我的 collectionView 之上。

正如你在这里提到的

collectionView.contentInset = UIEdgeInsets(top: -35, left: 0, bottom: 0, right: 0)

我认为这不是一个很好的解决方案,真正的原因是由 .grouped 产生的。控制整个contentView的偏移,contentInset不应该用来偏移header的效果(如下图)。


当您指定 UICollectionLayoutListConfiguration.grouped 模式时, 如果没有任何其他代码,您的 listConfig 默认表示 listConfig.headerMode = .nonelistConfig.footerMode = .none。 collectionView 将为每个部分生成一个 header 和一个页脚。

35 像素来自您的部分的高度 header.In 在这种情况下,我猜您只有一个部分,而且如您所见,底部必须有相同的额外填充。


  • 解决方案

1、listConfig.headerMode = .firstItemInSection

最方便最简单的方法

When you use this header mode, a UICollectionViewListCell object that appears as the first item in the section automatically uses a header appearance. When you configure your data source, make sure to account for the fact that the first item in the section (at index 0) represents the header, and the actual items in the section start at index 1.

2、listConfig.headerMode = .supplementary

您可以在 UICollectionViewDataSource

中完全自定义您的 header
    func collectionView(_ collectionView: UICollectionView, viewForSupplementaryElementOfKind kind: String, at indexPath: IndexPath) -> UICollectionReusableView {
        if (kind == UICollectionView.elementKindSectionHeader) {
            let header = collectionView.dequeueReusableSupplementaryView(ofKind: UICollectionView.elementKindSectionHeader, withReuseIdentifier: "your headerIdentifier", for: indexPath)
            ... // do some custom things
            return header
        }
        return UICollectionReusableView()
    }

别忘了这个

collectionView.register(UICollectionReusableView.self, forSupplementaryViewOfKind: UICollectionView.elementKindSectionHeader, withReuseIdentifier: "your headerIdentifier")