UICollectionView 中的节标题,仅出现第一个
Posted
技术标签:
【中文标题】UICollectionView 中的节标题,仅出现第一个【英文标题】:Section headers in UICollectionView, only first one appears 【发布时间】:2019-04-19 15:58:14 【问题描述】:我为节头创建了一个类,并将其加载到我的 UICollectionView 中。我能够显示第一个标题(尽管很奇怪,见下文),但是任何以下部分标题都是空白的。正在引用大小,但内容(背景颜色,标签)不会出现。
然后还有...确实显示的一个节标题,它以大约缩进显示。 150px 没有明显的原因。标题是否默认居中对齐?如果是这样,我将如何左对齐这些?
我的部分标题类:
func collectionView(_ collectionView: UICollectionView, viewForSupplementaryElementOfKind kind: String, at indexPath: IndexPath) -> UICollectionReusableView
switch kind
case UICollectionView.elementKindSectionHeader:
let section = indexPath.section
switch section
case 0:
let tagsHeader = searchCollectionView.dequeueReusableSupplementaryView(ofKind: kind, withReuseIdentifier: "TagsHeaderView", for: indexPath) as! SectionHeaderView
tagsHeader.headerString = "Recent Tags"
tagsHeader.backgroundColor = .green
return tagsHeader
default:
let tagsHeader = searchCollectionView.dequeueReusableSupplementaryView(ofKind: kind, withReuseIdentifier: "TypeHeaderView", for: indexPath) as! SectionHeaderView
tagsHeader.headerString = "Type"
tagsHeader.backgroundColor = .blue
return tagsHeader
default:
return UICollectionReusableView()
在我的 UICollectionView 中
func collectionView(_ collectionView: UICollectionView, viewForSupplementaryElementOfKind kind: String, at indexPath: IndexPath) -> UICollectionReusableView
switch kind
case UICollectionView.elementKindSectionHeader:
let section = indexPath.section
switch section
case 0:
let tagsHeader = searchCollectionView.dequeueReusableSupplementaryView(ofKind: kind, withReuseIdentifier: "TagsHeaderView", for: indexPath) as! SectionHeaderView
tagsHeader.headerString = "Recent Tags"
tagsHeader.backgroundColor = .green
return tagsHeader
default:
let tagsHeader = searchCollectionView.dequeueReusableSupplementaryView(ofKind: kind, withReuseIdentifier: "TypesHeaderView", for: indexPath) as! SectionHeaderView
tagsHeader.headerString = "Type"
tagsHeader.backgroundColor = .blue
return tagsHeader
default:
return UICollectionReusableView()
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, referenceSizeForHeaderInSection section: Int) -> CGSize
if section == 0
return CGSize(width: view.frame.width, height: 18 + 22 + 6)
else
return CGSize(width: view.frame.width, height: 100)
这就是我实例化 UICollectionView 的方式
let searchCollectionView: UICollectionView =
let layout = LeftAlignedCollectionViewFlowLayout()
layout.minimumInteritemSpacing = 6
layout.minimumLineSpacing = 6
let cv = UICollectionView(frame: .zero, collectionViewLayout: layout)
cv.isScrollEnabled = false
cv.register(TokenCell.self, forCellWithReuseIdentifier: "TokenCell")
cv.register(SectionHeaderView.self, forSupplementaryViewOfKind:UICollectionView.elementKindSectionHeader, withReuseIdentifier: "TagsHeaderView")
cv.register(SectionHeaderView.self, forSupplementaryViewOfKind:UICollectionView.elementKindSectionHeader, withReuseIdentifier: "TypesHeaderView")
cv.backgroundColor = .white
cv.showsVerticalScrollIndicator = false
cv.alwaysBounceVertical = false
cv.translatesAutoresizingMaskIntoConstraints = false
return cv
()
我的 CollectionViewFlowLayout
class LeftAlignedCollectionViewFlowLayout: UICollectionViewFlowLayout
override func layoutAttributesForElements(in rect: CGRect) -> [UICollectionViewLayoutAttributes]?
let attributes = super.layoutAttributesForElements(in: rect)
var leftMargin = sectionInset.left
var maxY: CGFloat = -1.0
attributes?.forEach layoutAttribute in
if layoutAttribute.frame.origin.y >= maxY
leftMargin = sectionInset.left
layoutAttribute.frame.origin.x = leftMargin
leftMargin += layoutAttribute.frame.width + minimumInteritemSpacing
maxY = max(layoutAttribute.frame.maxY , maxY)
return attributes
这是当前结果的屏幕截图。您可以看到第一个标题出现,但缩进。第二个标题有它的空间,但它的任何内容都没有出现。
【问题讨论】:
您确定要切换部分而不是行吗?通常只有一个部分有多行。问题可能在于您只有一个部分,因此永远不会调用默认值。尝试将使用“部分”一词的任何地方更改为“行” 是的,我很确定我想要部分。我的 collectionView 中有两个部分。这些项目正在显示,一切都在为此而努力。这只是第二个标题。我还设置了referenceSizeForHeaderInSection,它工作得很好。 您对我的默认情况未触发的部分是正确的。在那里设置断点,它永远不会到达。尝试将这种情况设置为 section == 1 也不是。这不是我到达我的部分或在每个部分放置单独标题的方式吗? 【参考方案1】:我在制作标签视图时遇到了同样的问题。
问题出在你的CollectionViewFlowLayout
。
let attributes = super.layoutAttributesForElements(in: rect)
这一行正在获取所有属性,包括单元格、补充视图和装饰视图,这意味着您也在更改页眉和页脚的属性。
我们可以把代码改成:
override func layoutAttributesForElements(in rect: CGRect) -> [UICollectionViewLayoutAttributes]?
let attributes = super.layoutAttributesForElements(in: rect)
var leftMargin = sectionInset.left
var maxY: CGFloat = -1.0
attributes?.forEach layoutAttribute in
//check if the layoutAttribute is for cell
if layoutAttribute.representedElementCategory == .cell
if layoutAttribute.frame.origin.y >= maxY
leftMargin = sectionInset.left
layoutAttribute.frame.origin.x = leftMargin
leftMargin += layoutAttribute.frame.width + minimumInteritemSpacing
maxY = max(layoutAttribute.frame.maxY , maxY)
return attributes
为了将属性应用于单元格。然后您的页眉和页脚将正确显示。
【讨论】:
以上是关于UICollectionView 中的节标题,仅出现第一个的主要内容,如果未能解决你的问题,请参考以下文章
更改 tableview 的 inset 时 UITableView 中的节标题