iOS: How to create Expandable TableView in Swift w

2020-08-01 11:30发布

问题:

I have Implemented Tableview in swift, but I want to Make Expandable TableView Please Give the idea..

This the code for Tableview..

//MARK: - TableView Delegate and Datasource
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
    return MenuNameArray.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    let cell = tableView.dequeueReusableCell(withIdentifier: "MenuTableViewCell", for: indexPath) as! MenuTableViewCell
    cell.menuNameLabel.text = NameArray[indexPath.row]
    return cell
}
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {

}

回答1:

Here You Go , Try This Out : -

struct ExpandableNames {
    var isExpanded : Bool
    var names : [String]
}

struct Contact {
    let names : String
}

in your Class - >

var twoDArray = [

    ExpandableNames(isExpanded : true,names:["Krishna","Rishabh","Aditya","Chandan","Nipun","Navdeesh","Steve"].map
    {
            Contact(names: $0)
    }),
    ExpandableNames(isExpanded : true,names:["Carl","Michal","Tommy","Jennny","Vikram","Swati"].map
    {
            Contact(names: $0)
    }),
    ExpandableNames(isExpanded : true,names:["David","dude","dfff","dcc","daa","dee","dsss"].map
    {
        Contact(names: $0)

    }),
    ExpandableNames(isExpanded : true,names:[Contact(names: "Pattrick", hasFav: false)])

                ]

let cellId = "cellID"
let identifier = "attachmentCellID"

func tableView(_ tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat
{
    return 50
}
func numberOfSections(in tableView: UITableView) -> Int
{

    return twoDArray.count

}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int
{
    if !twoDArray[section].isExpanded
    {
        return 0
    }
    return twoDArray[section].names.count
}
func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView?
{
    let btn = UIButton(type: .system)
    if(section == 0)
    {
        btn.setTitle("Tap To View Classes", for: .normal)
    }
    else if(section == 1)
    {
        btn.setTitle("Tap To View Admins", for: .normal)
    }

    btn.setTitleColor(.black, for: .normal)
    btn.titleLabel?.font = UIFont.boldSystemFont(ofSize: 14)
    btn.addTarget(self, action: #selector(handleExpandClose), for: .touchUpInside)
    btn.backgroundColor = AppColors.greyBorderColor
    btn.tag = section
    return btn
}
@objc func handleExpandClose(button : UIButton)
{
    let section = button.tag

    var indexPaths = [IndexPath]()
    for row in twoDArray[section].names.indices
    {
        let indexPath = IndexPath(row: row, section: section)
        indexPaths.append(indexPath)
    }

    let isExpanded = twoDArray[section].isExpanded
    twoDArray[section].isExpanded = !isExpanded


    button.setTitle(isExpanded ? "Tap To View Classes" : "Classes", for: .normal)



    if isExpanded
    {
        tableView.deleteRows(at: indexPaths, with: .fade)
    }
    else
    {
        tableView.insertRows(at: indexPaths, with: .fade)

    }


}

And Rest in cellForRowAt -

 let contact = twoDArray[indexPath.section].names[indexPath.row]
    cell.textLabel?.text = contact.names


回答2:

First you will need a model defining if the cell is open, for example, an array of indexPaths:

var openPaths = [IndexPath]()

now when select the cell you toggle wether it is open or not and reload the cell

        if let index = openPaths.index(indexPath) {
            openPaths.remove(atIndex: index)
        } else {
             openPaths.append(indexPath)
        }

        tableView.beginUpdates()
        tableView.reloadRows(at: [indexPath], with: .automatic)
        tableView.endUpdates()

Now in your cell setup, use a stackview, and in the cell config, you hide the expandable part based on if the cells indexPath is in openPaths



回答3:

Use heightForRowAt delegate method to change height of cell:- Add a boolean property to your object say isExpanded, change the value in didSelectRowAt delegate by

func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
    YourModel[indexPath.row].isExpanded = !YourModel[indexPath.row].isExpanded
    tableView.reloadRows(at: [indexPath], with: Animation)
}

func tableView(_ tableView: UITableView, estimatedHeightForRowAt indexPath: IndexPath) -> CGFloat {
    return 50
}

func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
     if YourModel[indexPath.row].isExpanded {
         return 200
     } else {
         return 50
     }
}