ios 如何使用swift在集合视图中制作页眉和页脚

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/29655652/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-31 05:38:00  来源:igfitidea点击:

How to make both header and footer in collection view with swift

iosswiftuicollectionview

提问by marrioa

How to make both header and footer in collection view in swift ?

如何在 swift 的集合视图中制作页眉和页脚?

I'm trying to combine a header and a footer together but it keep crashing, I couldn't find swift tutorial to understand it.

我试图将页眉和页脚组合在一起,但它一直崩溃,我找不到快速教程来理解它。

I don't how to return supplementary view for both rather just one .

我不知道如何为两者返回补充视图,而只是一个。

I set them both on the storyboard (class + identifier )

我将它们都设置在故事板上(类 + 标识符)

 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

}

Error:UICollectionElementKindCell with identifier one - must register a nib or a class for the identifier or connect a prototype cell in a storyboard'

错误:标识符为一的 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")
    }
}

I hope someone will help.

我希望有人会帮忙。

回答by Victor Sigler

You can make an UICollectionViewControllerto handle the UICollectionViewand in Interface Builder activate the Footerand Headersections, then you can use the following method for preview in you UICollectionViewthe two sections added :

您可以在 Interface Builder 中UICollectionViewController处理UICollectionView和激活页脚页眉部分,然后您可以使用以下方法在您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")
    }

In the above code I put the identifierfor the footer and header as Headerand Footerfor example, you can do it as you want. If you want to create a custom header or footer then you need to create a subclass of UICollectionReusableViewfor each and customize it as you want.

在上面的代码我把identifier页脚和头作为HeaderFooter例如,你可以做你想要的。如果要创建自定义页眉或页脚,则需要UICollectionReusableView为每个创建子类并根据需要对其进行自定义。

You can register your custom footer and header classes in Interface Builder or in code in the following way:

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

registerClass(myFooterViewClass, forSupplementaryViewOfKind: UICollectionElementKindSectionFooter, withReuseIdentifier: "myFooterView")

回答by mobilecat

Updated for Swift 3+

为 Swift 3+ 更新

Step 1:

第1步:

In your view controller class, register the class to be used as a header, footer, or both:

在您的视图控制器类中,注册要用作页眉、页脚或两者的类:

let collectionViewHeaderFooterReuseIdentifier = "MyHeaderFooterClass"

Step 2:

第2步:

If using a xib, use:

如果使用 xib,请使用:

collectionView.register(UINib(nibName: collectionViewHeaderFooterReuseIdentifier bundle: nil), forSupplementaryViewOfKind: UICollectionElementKindSectionHeader, withReuseIdentifier:collectionViewHeaderFooterReuseIdentifier)

collectionView.register(UINib(nibName: collectionViewHeaderFooterReuseIdentifier bundle: nil), forSupplementaryViewOfKind: UICollectionElementKindSectionFooter, withReuseIdentifier:collectionViewHeaderFooterReuseIdentifier)

If not using a xib:

如果不使用 xib:

collectionView.register(MyHeaderFooterClass.self, forSupplementaryViewOfKind: UICollectionElementKindSectionHeader, withReuseIdentifier: collectionViewHeaderFooterReuseIdentifier)

collectionView.register(MyHeaderFooterClass.self, forSupplementaryViewOfKind: UICollectionElementKindSectionFooter, withReuseIdentifier: collectionViewHeaderFooterReuseIdentifier)

Step 3:

第 3 步:

Create a custom header/footer class, implementation looks like:

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

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)

 }
}

Step 4:If not using a xib, ignore

第 4 步:如果不使用 xib,请忽略

  • Create a new empty xib: "File --> New File --> Empty".

  • Name it the exact same nameas the class. In this example: "MyHeaderFooterClass"

  • Add a collection reusable view to the xib.
  • Click on that object, select the Identity Inspector and change the class of that object to "MyHeaderFooterClass".
  • 创建一个新的空 xib:“文件 --> 新文件 --> 空”。

  • 将其命名为与类完全相同的名称。在这个例子中:“MyHeaderFooterClass”

  • 将集合可重用视图添加到 xib。
  • 单击该对象,选择 Identity Inspector 并将该对象的类更改为“MyHeaderFooterClass”。

Step 5:- Support that new cell in your collection view via delegate method:

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

Step 6:Handle size / make it appear:

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

回答by Bruno Cunha

Just to complement the remaining answers, don't forget to allocate space for your header/footer views, otherwise collectionView:viewForSupplementaryElementOfKind:atIndexPathwon't be called.

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

Do so by implementing collectionView:layout:referenceSizeForHeaderInSectionin your collectionView datasource.

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

回答by Ahmed Abdallah

After using @mobilecat code you should use this function to make the header and footer appear

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

回答by Zanael

Solution

解决方案

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

回答by genius

In addition to all answers above

除了以上所有答案

To activate the Footer and Header sections

激活页脚和页眉部分

Select your collection then select Attributes inspector and check on the Footer and Header sections

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

like in photo

就像照片一样

enter image description here

在此处输入图片说明

回答by Pramodya Abeysinghe

if you need to keep empty spaces for header and footer make an extension of UICollectionViewDelegateFlowLayoutand use this code to set header or footer accordingly.

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

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

回答by Carlos Perez Perez

Note that your viewController must implement UICollectionViewDelegateFlowLayout or these methods won't get called

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

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

}

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

}