insert/ delete sections in cells UICollectionView

828 views Asked by At

Good afternoon,

I am trying to create expandable/ collapsible cells in a UICollectionViewController. The cells expand and collapse correctly. However, the information each cell holds stays present on the screen in the background. I will show pictures to explain. I am trying to delete the information from the view if the user collapses the cell, and insert it back if the user expands that cell.

The images below express the process of the cell starting in a collapsed state, expanding that cell, them collapsing that cell again. (note: this happens to every cell not just the first cell I clicked.

the first image is when the view loads and the cells are in the original collapsed state.

collapsed state

this second image shows when the user taps on the cell to expand it.

expanded cell

the third image shows when the user tries to collapse the cell.

collapsing that cell again

the code that I use to expand and collapse the cells are below

fileprivate let cellId = "cellId"
fileprivate let headerId = "headerId"
fileprivate let profID = "profID"
private let headerIdentifier = "userProfileHeader"
private let sectionIdentifier = "sectionHeader"
var section:Int?
var expandSection = [Bool]()
var items = [String]()

    fileprivate func setupCollectionView() {
    collectionView.backgroundColor = .white
    collectionView.contentInsetAdjustmentBehavior = .never
    collectionView.register(UICollectionViewCell.self, forCellWithReuseIdentifier: cellId)
    self.expandSection = [Bool](repeating: false, count: self.items.count)
    collectionView.dataSource = self
    collectionView.delegate = self
    collectionView.register(userProfileHeader.self, forSupplementaryViewOfKind: UICollectionView.elementKindSectionHeader, withReuseIdentifier: headerIdentifier)

    collectionView.register(sectionHeader.self, forSupplementaryViewOfKind: UICollectionView.elementKindSectionHeader, withReuseIdentifier: sectionIdentifier)
}

    fileprivate func registerCollectionView() {

collectionView.register(profCell.self, forCellWithReuseIdentifier: "profCell")
    self.collectionView.register(userProfileHeader.self, forSupplementaryViewOfKind: UICollectionView.elementKindSectionHeader, withReuseIdentifier: headerIdentifier)

     self.collectionView.register(sectionHeader.self, forSupplementaryViewOfKind: UICollectionView.elementKindSectionHeader, withReuseIdentifier: sectionIdentifier)
}



var headerView: userProfileHeader?
var sectionView: sectionHeader?

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

    if kind == UICollectionView.elementKindSectionHeader {
         let headerView = collectionView.dequeueReusableSupplementaryView(ofKind: kind, withReuseIdentifier: headerIdentifier, for: indexPath) as? userProfileHeader

        if let user = self.user {
                 headerView?.myUser = user
             } else if let userToLoad = self.userToLoad {
                 headerView?.myUser  = userToLoad
             }

        return headerView!
    } else {

        let sectionViews = collectionView.dequeueReusableSupplementaryView(ofKind: kind, withReuseIdentifier: sectionIdentifier, for: indexPath) as? sectionHeader
        let categories = ["Skills, Preferences", "Bio", "Reviews"]
        sectionViews!.headerLabel.text = categories[indexPath.section]
        sectionViews!.backgroundColor = .lightGray
        return sectionViews!
    }

}

    func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, referenceSizeForHeaderInSection section: Int) -> CGSize {
    return .init(width: view.frame.width, height: 340)
}

override func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
    return items.count
}

override func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {

    self.expandSection[indexPath.row] = !self.expandSection[indexPath.row]
    self.collectionView.reloadItems(at: collectionView.indexPathsForSelectedItems!)
}

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

    if indexPath.row == 0 {

        cell.educationView.text = user.education
        cell.skillsView.text = user.skills
        cell.preferencesView.text = "wassup bitches"

    } else if indexPath.row == 1  {

        cell.bioLabel.text = user.bio

    } else if indexPath.row == 2  {

        cell.labels.text = "Reviews"

    }
    }

    return cell
}

func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {

    if self.expandSection[indexPath.row] {
        return CGSize(width: self.view.bounds.width - 20, height: 300)
    }else{
        return CGSize(width: self.view.bounds.width - 20, height: 80)
    }
}
1

There are 1 answers

7
FryAnEgg On

Instead of trying to insert and remove items inside sizeForItemAt(), call reloadSections(_ sections: IndexSet) for the sections that get expanded or contracted. Then implement numberOfItems(inSection section: Int) to return 0 when contracted or items.count when expanded. Use sections to hold the top level items and cells to hold the collapsible sub-items.