如何使用swift在uicollectionview中创建页眉和页脚

时间:2015-04-15 16:23:00

标签: ios swift uicollectionview

如何在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

}
  

错误:   标识符为1的UICollectionElementKindCell - 必须为标识符注册一个nib或类,或者在故事板中连接原型单元格'

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

我希望有人会帮忙。

10 个答案:

答案 0 :(得分:61)

您可以让UICollectionViewController来处理UICollectionView,并在Interface Builder中激活页脚标题部分,然后您就可以使用您可以按照以下方法预览[{1}}这两个部分:

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") } 作为页脚和标题放置为identifierHeader,例如,您可以根据需要执行此操作。如果要创建自定义页眉或页脚,则需要为每个创建一个Footer的子类,并根据需要对其进行自定义。

您可以通过以下方式在Interface Builder或代码中注册自定义页脚和标题类:

UICollectionReusableView

答案 1 :(得分:15)

针对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)

第3步:

创建自定义页眉/页脚类,实现如下:

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”

  • 向xib添加可重用的集合视图。
  • 单击该对象,选择Identity Inspector并将该对象的类更改为“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)
}

答案 2 :(得分:5)

为了补充剩余的答案,请不要忘记为页眉/页脚视图分配空间,否则将不会调用collectionView:viewForSupplementaryElementOfKind:atIndexPath

通过在collectionView数据源中实现collectionView:layout:referenceSizeForHeaderInSection来实现。

答案 3 :(得分:4)

使用@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)
    }

答案 4 :(得分:1)

解决方案

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

答案 5 :(得分:1)

请注意,您的viewController必须实现UICollectionViewDelegateFlowLayout,否则这些方法将不会被调用

func collectionView(_ collectionView: UICollectionView, viewForSupplementaryElementOfKind kind: String, at indexPath: IndexPath) -> UICollectionReusableView {

}

func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, referenceSizeForHeaderInSection section: Int) -> CGSize {

}

答案 6 :(得分:1)

除了以上所有答案

激活页脚和页眉部分

选择您的集合,然后选择“属性”检查器,然后检查“页脚”和“页眉”部分

像照片一样

enter image description here

答案 7 :(得分:1)

如果需要在页眉和页脚保留空白,请扩展UICollectionViewDelegateFlowLayout并使用此代码相应地设置页眉或页脚。

override func viewDidLayoutSubviews() {
    super.viewDidLayoutSubviews()
    let footerValue = 150
    let headerValue = 150
    collectionView.contentInset = UIEdgeInsets(top: headerValue, left: 0, bottom: footerValue, right: 0)
}

答案 8 :(得分:0)

Xcode 11+和iOS 13 +

我正在使用Xib创建页眉和页脚视图

  1. 像这样为Header和Footer创建Xibs和Class文件(与Footer类相同),并为两者创建xib视图
class HeaderViewCV: UICollectionReusableView {

}
  1. 像这样注册Xib细胞
collectionView.register(UINib(nibName: "HeaderViewCV", bundle: nil), forSupplementaryViewOfKind: UICollectionView.elementKindSectionHeader, withReuseIdentifier: "HeaderViewCV") //elementKindSectionFooter for footerview
  1. 页眉和页脚查看方法
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")
    }
}
  1. 对于两者的查看高度方法
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)
}
  1. 已完成CollectionView中页眉和页脚的所有必要要求

答案 9 :(得分:0)

按照@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
  }