Android teem
Android teem

Reputation: 830

Custom cells for expandable UiTableView

I have a data set that has an inner array and I have to show that Inner array in Expand collapse fashion.

For that I have designed 2 nib files. One for the sections, and other for the cell in sections.

I have attached UitableView and the delegated methods. I am successful to show the Header view, I am registering the header view like this.

let nib = UINib.init(nibName: "headerItemSavedListCell", bundle: nil)
self.lvSavedList.register(nib, forCellReuseIdentifier: "headerItemSavedListCell")

and for cell I am doing in the following method

if(indexPath.row == 0){
    let header = Bundle.main.loadNibNamed("headerItemSavedListCell", owner: self, options: nil)?.first as! headerItemSavedListCell

    return header

}else{

    let cell = Bundle.main.loadNibNamed("ItemSavedListCell", owner: self, options: nil)?.first as! ItemSavedListCell

    return cell
}

But its not working.

**So my questions is: **

Please help if you have any tutorial regarding expandable Uitableview

Upvotes: 0

Views: 43

Answers (1)

Devil Decoder
Devil Decoder

Reputation: 1086

the class i am using here are connected to xibs

make xib of view and bind below class so first you have to make headerview like below

protocol HeaderDelegate:class{
func didSelectHeader(Header:HeaderFooter,at index:Int)
}

class HeaderFooter: UITableViewHeaderFooterView {
@IBOutlet weak var lblTitle: UILabel!

weak var delegate:HeaderDelegate?
var Expand = false

override func awakeFromNib() {
    let tap = UITapGestureRecognizer.init(target: self, action: #selector(didSelect(_:)))
    self.addGestureRecognizer(tap)
    self.isUserInteractionEnabled = true
}

@objc func didSelect(_ tap:UITapGestureRecognizer)
{
    delegate?.didSelectHeader(Header: self, at: self.tag)
}

override func prepareForReuse() {
    Expand = false
}
}

above i added tap gesture to detect touch on headerViews

next make cell like below

class ExpandableCell: UITableViewCell {

var isExpanded = false
override func awakeFromNib() {
    super.awakeFromNib()
    isExpanded = false
    // Initialization code
}

override func setSelected(_ selected: Bool, animated: Bool) {
    super.setSelected(selected, animated: animated)

    // Configure the view for the selected state
}

}

in your view controller

tblView.register(UINib.init(nibName: "HeaderFooter", bundle: nil), forHeaderFooterViewReuseIdentifier: "HeaderFooter")

in tablview dataSorce and Delegate Method

func numberOfSections(in tableView: UITableView) -> Int {
    return numberofsections
}

func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
    return numberofrows
}

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    guard let cell = tableView.dequeueReusableCell(withIdentifier: "ExpandableCell") as? ExpandableCell else {
        return UITableViewCell()
    }
    //configure cell here
    return cell
}

func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
    guard let header = tableView.headerView(forSection: indexPath.section) as? HeaderFooter
        else {return 0}
    if header.Expand
    {
        return UITableViewAutomaticDimension
    }
    else
    {
        return 0
    }
}

func tableView(_ tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat {
    return UITableViewAutomaticDimension
}
func tableView(_ tableView: UITableView, estimatedHeightForHeaderInSection section: Int) -> CGFloat {
     return 50
}
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {

}

func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {
    guard let headerView = tableView.dequeueReusableHeaderFooterView(withIdentifier: "HeaderFooter") as? HeaderFooter else {return nil}
    //configure header View here
    headerView.tag = section
    return headerView
}
//MARK:-headerDelegate
func didSelectHeader(Header: HeaderFooter, at index: Int) {
    Header.Expand = !Header.Expand
    //comment below part if you dont want to collapse other rows when other section opened
    for i in 0..<tblView.numberOfSections
    {
        if i != index
        {
            guard let header = tblView.headerView(forSection: i) as? HeaderFooter else {return}
            header.Expand = false
            for j in 0..<tblView.numberOfRows(inSection: i)
            {
                tblView.reloadRows(at: [IndexPath.init(row: j, section: i)], with: .automatic)
            }
        }
        else
        {
            for j in 0..<tblView.numberOfRows(inSection: i)
            {
                tblView.reloadRows(at: [IndexPath.init(row: j, section: i)], with: .automatic)
            }
        }
    }
}

Upvotes: 0

Related Questions