如何在 swift 中在集合视图中同时制作页眉和页脚?
我试图将页眉和页脚组合在一起,但它一直崩溃,我找不到快速教程来理解它。
我不知道如何返回两者的补充视图,而只是一个。
我将它们都设置在故事板上(类+标识符)
override func numberOfSectionsInCollectionView(collectionView: UICollectionView) -> Int {
//#warning Incomplete method implementation -- Return the number of sections
return 2
}
override func collectionView(collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
//#warning Incomplete method implementation -- Return the number of items in the section
return 10
}
override func collectionView(collectionView: UICollectionView, viewForSupplementaryElementOfKind kind: String, atIndexPath indexPath: NSIndexPath) -> UICollectionReusableView {
var header: headerCell!
var footer: footerCell!
if kind == UICollectionElementKindSectionHeader {
header =
collectionView.dequeueReusableSupplementaryViewOfKind(kind,
withReuseIdentifier: "header", forIndexPath: indexPath)
as? headerCell
}
return header
}
错误: 标识符为一的 UICollectionElementKindCell - 必须为标识符注册一个笔尖或一个类,或者连接故事板中的原型单元'
override func collectionView(collectionView: UICollectionView, cellForItemAtIndexPath indexPath: NSIndexPath) -> profileCC {
let cell = collectionView.dequeueReusableCellWithReuseIdentifier("one", forIndexPath: indexPath) as! profileCC
// Configure the cell
return cell
}
override func collectionView(collectionView: UICollectionView, viewForSupplementaryElementOfKind kind: String, atIndexPath indexPath: NSIndexPath) -> UICollectionReusableView {
switch kind {
case UICollectionElementKindSectionHeader:
let headerView = collectionView.dequeueReusableSupplementaryViewOfKind(kind, withReuseIdentifier: "header", forIndexPath: indexPath) as! headerCell
headerView.backgroundColor = UIColor.blueColor();
return headerView
case UICollectionElementKindSectionFooter:
let footerView = collectionView.dequeueReusableSupplementaryViewOfKind(kind, withReuseIdentifier: "footer", forIndexPath: indexPath) as! footerCell
footerView.backgroundColor = UIColor.greenColor();
return footerView
default:
assert(false, "Unexpected element kind")
}
}
希望有人帮忙。
您可以制作一个
UICollectionViewController
来处理UICollectionView
,并在Interface Builder中激活Footer和Header部分,然后您可以使用以下方法在您的UICollectionView
中预览添加的两个部分:
override func collectionView(collectionView: UICollectionView, viewForSupplementaryElementOfKind kind: String, atIndexPath indexPath: NSIndexPath) -> UICollectionReusableView {
switch kind {
case UICollectionView.elementKindSectionHeader:
let headerView = collectionView.dequeueReusableSupplementaryView(ofKind: kind, withReuseIdentifier: "Header", for: indexPath)
headerView.backgroundColor = UIColor.blue
return headerView
case UICollectionView.elementKindSectionFooter:
let footerView = collectionView.dequeueReusableSupplementaryView(ofKind: kind, withReuseIdentifier: "Footer", for: indexPath)
footerView.backgroundColor = UIColor.green
return footerView
default:
assert(false, "Unexpected element kind")
}
}
在上面的代码中,我将页脚和页眉的
identifier
设置为Header
和Footer
,例如,您可以按照自己的意愿进行操作。如果您想创建自定义页眉或页脚,那么您需要为每个页眉或页脚创建一个 UICollectionReusableView
的子类,并根据需要对其进行自定义。
您可以在 Interface Builder 中或在代码中注册自定义页脚和页眉类:
registerClass(myFooterViewClass, forSupplementaryViewOfKind: UICollectionElementKindSectionFooter, withReuseIdentifier: "myFooterView")
更新为 Swift 3+
第1步:
在视图控制器类中,注册要用作页眉、页脚或两者的类:
let collectionViewHeaderFooterReuseIdentifier = "MyHeaderFooterClass"
第2步:
如果使用 xib,请使用:
collectionView.register(UINib(nibName: collectionViewHeaderFooterReuseIdentifier bundle: nil), forSupplementaryViewOfKind: UICollectionElementKindSectionHeader, withReuseIdentifier:collectionViewHeaderFooterReuseIdentifier)
collectionView.register(UINib(nibName: collectionViewHeaderFooterReuseIdentifier bundle: nil), forSupplementaryViewOfKind: UICollectionElementKindSectionFooter, withReuseIdentifier:collectionViewHeaderFooterReuseIdentifier)
如果不使用 xib:
collectionView.register(MyHeaderFooterClass.self, forSupplementaryViewOfKind: UICollectionElementKindSectionHeader, withReuseIdentifier: collectionViewHeaderFooterReuseIdentifier)
collectionView.register(MyHeaderFooterClass.self, forSupplementaryViewOfKind: UICollectionElementKindSectionFooter, withReuseIdentifier: collectionViewHeaderFooterReuseIdentifier)
第三步:
创建自定义页眉/页脚类,实现如下:
import UIKit
class MyHeaderFooterClass: UICollectionReusableView {
override init(frame: CGRect) {
super.init(frame: frame)
self.backgroundColor = UIColor.purple
// Customize here
}
required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
}
}
第 4 步: 如果不使用 xib,请忽略
创建一个新的空 xib:“文件 --> 新文件 --> 空”。
将其命名为与类完全相同的名称。 在此示例中:“MyHeaderFooterClass”
第5步: - 通过委托方法支持集合视图中的新单元格:
func collectionView(_ collectionView: UICollectionView,
viewForSupplementaryElementOfKind kind: String,
at indexPath: IndexPath) -> UICollectionReusableView {
switch kind {
case UICollectionElementKindSectionHeader:
let headerView = collectionView.dequeueReusableSupplementaryView(ofKind: kind, withReuseIdentifier: collectionViewHeaderFooterReuseIdentifier, for: indexPath)
headerView.backgroundColor = UIColor.blue
return headerView
case UICollectionElementKindSectionFooter:
let footerView = collectionView.dequeueReusableSupplementaryView(ofKind: kind, withReuseIdentifier: collectionViewHeaderFooterReuseIdentifier, for: indexPath)
footerView.backgroundColor = UIColor.green
return footerView
default:
assert(false, "Unexpected element kind")
}
}
第6步: 手柄尺寸/使其出现:
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, referenceSizeForHeaderInSection section: Int) -> CGSize {
return CGSize(width: collectionView.frame.width, height: 180.0)
}
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, referenceSizeForFooterInSection section: Int) -> CGSize {
return CGSize(width: 60.0, height: 30.0)
}
为了补充剩余的答案,不要忘记为页眉/页脚视图分配空间,否则
collectionView:viewForSupplementaryElementOfKind:atIndexPath
不会被调用。
通过在 collectionView 数据源中实现
collectionView:layout:referenceSizeForHeaderInSection
来实现这一点。
Xcode 11+ 和 iOS 13+
我正在使用 Xib 创建页眉和页脚视图
class HeaderViewCV: UICollectionReusableView {
}
collectionView.register(UINib(nibName: "HeaderViewCV", bundle: nil), forSupplementaryViewOfKind: UICollectionView.elementKindSectionHeader, withReuseIdentifier: "HeaderViewCV") //elementKindSectionFooter for footerview
func collectionView(_ collectionView: UICollectionView, viewForSupplementaryElementOfKind kind: String, at indexPath: IndexPath) -> UICollectionReusableView {
switch kind {
case UICollectionView.elementKindSectionHeader:
let headerView = collectionView.dequeueReusableSupplementaryView(ofKind: kind, withReuseIdentifier: "HeaderViewCV", for: indexPath)
return headerView
case UICollectionView.elementKindSectionFooter:
let footerView = collectionView.dequeueReusableSupplementaryView(ofKind: kind, withReuseIdentifier: "FooterViewCV", for: indexPath)
return footerView
default:
assert(false, "Unexpected element kind")
}
}
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, referenceSizeForHeaderInSection section: Int) -> CGSize {
return CGSize(width: self.collectionView.frame.width, height: 55)
}
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, referenceSizeForFooterInSection section: Int) -> CGSize {
return CGSize(width: self.collectionView.frame.width, height: 67)
}
使用@mobilecat代码后,您应该使用此功能使页眉和页脚出现
func collectionView(
_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout,
referenceSizeForHeaderInSection section: Int
) -> CGSize {
return CGSize(width: collectionView.frame.width, height: 180.0)
}
func collectionView(
_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout,
referenceSizeForFooterInSection section: Int
) -> CGSize {
return CGSize(width: 60.0, height: 30.0)
}
解决方案
class CustomFlowLayout: UICollectionViewFlowLayout {
override func layoutAttributesForElements(in rect: CGRect) -> [UICollectionViewLayoutAttributes]? {
let attributesForElementsInRect = super.layoutAttributesForElements(in: rect)
var newAttributesForElementsInRect = [UICollectionViewLayoutAttributes]()
for attributes in attributesForElementsInRect! {
if !(attributes.representedElementKind == UICollectionElementKindSectionHeader
|| attributes.representedElementKind == UICollectionElementKindSectionFooter) {
// cells will be customise here, but Header and Footer will have layout without changes.
}
newAttributesForElementsInRect.append(attributes)
}
return newAttributesForElementsInRect
}
}
class YourViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
let headerNib = UINib.init(nibName: "HeaderCell", bundle: nil)
collectionView.register(headerNib, forSupplementaryViewOfKind: UICollectionElementKindSectionHeader, withReuseIdentifier: "HeaderCell")
let footerNib = UINib.init(nibName: "FooterCell", bundle: nil)
collectionView.register(footerNib, forSupplementaryViewOfKind: UICollectionElementKindSectionFooter, withReuseIdentifier: "FooterCell")
}
func collectionView(_ collectionView: UICollectionView, viewForSupplementaryElementOfKind kind: String, at indexPath: IndexPath) -> UICollectionReusableView {
switch kind {
case UICollectionElementKindSectionHeader:
let headerView = collectionView.dequeueReusableSupplementaryView(ofKind: kind, withReuseIdentifier: "HeaderCell", for: indexPath) as! HeaderCell
return headerView
case UICollectionElementKindSectionFooter:
let footerView = collectionView.dequeueReusableSupplementaryView(ofKind: kind, withReuseIdentifier: "FooterCell", for: indexPath) as! FooterCell
return footerView
default:
return UICollectionReusableView()
}
}
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, referenceSizeForHeaderInSection section: Int) -> CGSize {
return CGSize(width: collectionView.frame.width, height: 45)
}
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, referenceSizeForFooterInSection section: Int) -> CGSize {
return CGSize(width: collectionView.frame.width, height: 25)
}
}
如果您需要为页眉和页脚保留空白空间,请扩展
UICollectionViewDelegateFlowLayout
并使用此代码相应地设置页眉或页脚。
override func viewDidLayoutSubviews() {
super.viewDidLayoutSubviews()
let footerValue = 150
let headerValue = 150
collectionView.contentInset = UIEdgeInsets(top: headerValue, left: 0, bottom: footerValue, right: 0)
}
请注意,您的 viewController 必须实现 UICollectionViewDelegateFlowLayout ,否则这些方法将不会被调用
func collectionView(_ collectionView: UICollectionView, viewForSupplementaryElementOfKind kind: String, at indexPath: IndexPath) -> UICollectionReusableView {
}
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, referenceSizeForHeaderInSection section: Int) -> CGSize {
}
以下@mobilecat详细答案,如果您使用组合集合视图,请在创建布局时添加这些行:
let headerSize = NSCollectionLayoutSize(widthDimension: .fractionalWidth(1.0), heightDimension: .estimated(44))
let headerElement = NSCollectionLayoutBoundarySupplementaryItem(layoutSize: headerSize, elementKind: UICollectionView.elementKindSectionHeader, alignment: .top)
并将
headerElement
设置为您的部分,如下所示:
let section = NSCollectionLayoutSection(group: group)
section.boundarySupplementaryItems = [headerElement]
完整的代码片段是:
private func createCompositionalLayout() -> UICollectionViewCompositionalLayout {
let itemSize = NSCollectionLayoutSize(widthDimension: .fractionalHeight(1.0),
heightDimension: .fractionalHeight(0.2))
let item = NSCollectionLayoutItem(layoutSize: itemSize)
let groupSize = NSCollectionLayoutSize(widthDimension: .fractionalWidth(1.0),
heightDimension: .fractionalWidth(1.0))
let group = NSCollectionLayoutGroup.vertical(layoutSize: groupSize, subitems: [item])
let headerSize = NSCollectionLayoutSize(widthDimension: .fractionalWidth(1.0), heightDimension: .estimated(44))
let headerElement = NSCollectionLayoutBoundarySupplementaryItem(layoutSize: headerSize, elementKind: UICollectionView.elementKindSectionHeader, alignment: .top)
let section = NSCollectionLayoutSection(group: group)
section.boundarySupplementaryItems = [headerElement]
let layout = UICollectionViewCompositionalLayout(section: section)
return layout
}