代码之家  ›  专栏  ›  技术社区  ›  sarah

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

  •  5
  • sarah  · 技术社区  · 7 年前

    enter image description here

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

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

    enter image description here

    我曾尝试编写代码,但它似乎有时可以扩展,有时无法扩展(仍显示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相同。节,但它似乎有所不同,但我不知道如何访问indexPath。集合中的节 截面中的项目数 方法

    如何解决这个问题?

    1 回复  |  直到 7 年前
        1
  •  2
  •   Shehata Gamal    7 年前

    您必须在内部指定当前状态 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)
    
    }