ios – 如何在swift中创建可扩展的集合视图?

《ios – 如何在swift中创建可扩展的集合视图?》

我有2个集合视图部分,当第一次加载此VC时,两个部分(室内和室外)最初将只显示3个项目.

但是在用户按下“更多”按钮后,室内或室外的每个部分都会展开并显示所有可用项目,如下图所示

《ios – 如何在swift中创建可扩展的集合视图?》

我试图制作代码,但有时它似乎可以扩展,有时它不会扩展(仍显示3项).

这是主控制器中的代码:

class FacilitiesVC: UIViewController {

    @IBOutlet weak var collectionView: UICollectionView!

    var facilitiesCategoryData = [[String:Any]]()
    var outdoorFacilitiesIsExpanded = false
    var indoorFacilitiesIsExpanded = false

    override func viewDidLoad() {
        super.viewDidLoad()

        getIndoorOutdoorFacilitiesData()
    }

}

extension FacilitiesVC {

    // MARK: - Helper Methods

    func getIndoorOutdoorFacilitiesData() {

        let facilitiesData = FacilitiesCategoryLibrary.fetchFacilitiesCategory()
        var indoorFacilities = [FacilitiesCategory]()
        var outdoorFacilities = [FacilitiesCategory]()

        // distinguishing between indoor and outdoor data
        for facData in facilitiesData {

            if facData.type == "Indoor Facility" {
                indoorFacilities.append(facData)
            } else {
                outdoorFacilities.append(facData)
            }
        }

        facilitiesCategoryData = [
            ["title": "Indoor Facilities", "info": indoorFacilities],
            ["title": "Outdoor Facilities", "info": outdoorFacilities]
        ]
    }

}

extension FacilitiesVC: UICollectionViewDataSource {

    // MARK: - UICollectionViewDataSource

    func numberOfSections(in collectionView: UICollectionView) -> Int {
        return facilitiesCategoryData.count
    }

    func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {

        if section == 0 {

            if indoorFacilitiesIsExpanded {
                let category = facilitiesCategoryData[section]
                let infoList = category["info"] as! [FacilitiesCategory]
                return infoList.count
            } else {
                return 3
            }

        } else {

            if outdoorFacilitiesIsExpanded {
                let category = facilitiesCategoryData[section]
                let infoList = category["info"] as! [FacilitiesCategory]
                return infoList.count
            } else {
                return 3
            }

        }
    }

    func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
        let cell = collectionView.dequeueReusableCell(withReuseIdentifier: StoryBoard.facilitiesCategoryCellIdentifier, for: indexPath) as! FacilitiesCell

        let category = facilitiesCategoryData[indexPath.section]
        let infoList = category["info"] as! [FacilitiesCategory]
        cell.facilitiesCategoryData = infoList[indexPath.item]

        return cell
    }

    // for section header view
    func collectionView(_ collectionView: UICollectionView, viewForSupplementaryElementOfKind kind: String, at indexPath: IndexPath) -> UICollectionReusableView {

        let sectionHeaderView = collectionView.dequeueReusableSupplementaryView(ofKind: kind, withReuseIdentifier: StoryBoard.facilitiesSectionHeaderIdentifier, for: indexPath) as! FacilitiesSectionHeader

        let category = facilitiesCategoryData[indexPath.section]
        sectionHeaderView.categoryData = category
        sectionHeaderView.sectionHeaderDelegate = self

        return sectionHeaderView
    }

}

extension FacilitiesVC: FacilitiesSectionHeaderDelegate {

    func didPressButton(_ facilities: String, isExpanded: Bool) {

        if facilities == "Indoor Facilities" {
            indoorFacilitiesIsExpanded = isExpanded
        } else if facilities == "Outdoor Facilities" {
            outdoorFacilitiesIsExpanded = isExpanded
        }

        collectionView.reloadData()
    }

}

这是集合视图部分标题中的代码

import UIKit

protocol FacilitiesSectionHeaderDelegate: class {
    func didPressButton(_ facilities: String, isExpanded: Bool)
}

class FacilitiesSectionHeader: UICollectionReusableView {

    @IBOutlet weak var titleLabel: UILabel!

    weak var sectionHeaderDelegate: FacilitiesSectionHeaderDelegate?

    var collectionIsExpanded = false
    var facilitiesType = ""

    var categoryData: [String:Any]! {
        didSet {
            titleLabel.text = categoryData["title"] as? String
            facilitiesType = categoryData["title"] as! String
        }
    }

    @IBAction func moreButtonDidPressed(_ sender: Any) {
        collectionIsExpanded = !collectionIsExpanded
        sectionHeaderDelegate?.didPressButton(facilitiesType, isExpanded: collectionIsExpanded)
    }

}

也许我在这行代码中收集numberOfItemsInSection中的错误

func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {

    if section == 0 {

        if indoorFacilitiesIsExpanded {
            let category = facilitiesCategoryData[section]
            let infoList = category["info"] as! [FacilitiesCategory]
            return infoList.count
        } else {
            return 3
        }

    } else {

        if outdoorFacilitiesIsExpanded {
            let category = facilitiesCategoryData[section]
            let infoList = category["info"] as! [FacilitiesCategory]
            return infoList.count
        } else {
            return 3
        }

    }
}

我认为该section参数与indexPath.section相同,但似乎有所不同,但我不知道如何从collection numberOfItemsInSection方法访问indexPath.section

怎么解决这个问题?

最佳答案 您必须在viewForSupplementaryElementOfKind中分配当前状态

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

    let sectionHeaderView = collectionView.dequeueReusableSupplementaryView(ofKind: kind, withReuseIdentifier: StoryBoard.facilitiesSectionHeaderIdentifier, for: indexPath) as! FacilitiesSectionHeader

    let category = facilitiesCategoryData[indexPath.section]
    sectionHeaderView.categoryData = category
    sectionHeaderView.sectionHeaderDelegate = self

    if(indexPath.section == 0)
    {
       sectionHeaderView.collectionIsExpanded =  indoorFacilitiesIsExpanded
    }
    else
    {
      sectionHeaderView.collectionIsExpanded = outdoorFacilitiesIsExpanded
    }

    return sectionHeaderView
}

在FacilitiesSectionHeader内部,你可以根据它进行翻转

 @IBAction func moreButtonDidPressed(_ sender: Any) {

    collectionIsExpanded = !collectionIsExpanded
    sectionHeaderDelegate?.didPressButton(facilitiesType, isExpanded: collectionIsExpanded)

}
点赞