Home > Back-end >  How to make Expandable with only Cells (NOT SECTION/ HEADER) with UITableView in Swift?
How to make Expandable with only Cells (NOT SECTION/ HEADER) with UITableView in Swift?

Time:12-05

I researched all StackOverflow about Expandable Table View, but they have posted only a show header with the cells. In fact that iOS 15 has changed the new design interfaces of the UITableView as known .insetGrouped.

Basically Header in .insetGrouped really terrible design interfaces for Expandable. I am trying to get my idea to use only cell to do Expandable without section needed.

My Table View codes Here:

class HelpViewController: UIViewController, UITableViewDelegate, UITableViewDataSource {
    
    struct Object {
        var seactionName: String!
        var seactionObjection: [String]!
        var footerName: String!
    }
   
    var objectArray = [Object]()
    
    
    var TableView = UITableView()
    
    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view.
        
        
        objectArray = [
            Object(seactionName: "Header", seactionObjection: ["Expandable Cell", "One Row", "Two Row"],
                   
                footerName: "Footer"),
        
            
            // copy and paste new cells
        ]
   
        title = "Help Center"
        
        view.backgroundColor = UIColor.quaternarySystemFill
    
        TableView.frame = view.bounds
       
        TableView = UITableView(frame: self.view.bounds, style: UITableView.Style.insetGrouped)
        TableView.showsVerticalScrollIndicator = true
        TableView.indicatorStyle = .default
        TableView.register(SliceCell.self, forCellReuseIdentifier: "Slice List")
        
        TableView.delegate = self
        TableView.dataSource = self
        
        view.addSubview(TableView)
    
    }


    
    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return objectArray[section].seactionObjection.count
    }
    
    func numberOfSections(in tableView: UITableView) -> Int {
       
        return objectArray.count
        
    }
    
        func tableView(_ tableView: UITableView, titleForHeaderInSection section: Int) -> String? {

            return objectArray[section].seactionName

        }



func tableView(_ tableView: UITableView, titleForFooterInSection section: Int) -> String? {
    return objectArray[section].footerName
}
    
    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
  
        
        let cell = tableView.dequeueReusableCell(withIdentifier: "Slice List") as! SliceCell
        
        cell.backgroundColor = .secondarySystemGroupedBackground
            cell.textLabel?.text = objectArray[indexPath.section].seactionObjection[indexPath.row]
            cell.textLabel?.numberOfLines = 0
        
        return cell
    }

func tableView(_ tableView: UITableView, willDisplayHeaderView view: UIView, forSection section: Int){
    view.tintColor = .clear
    let header = view as! UITableViewHeaderFooterView
    header.textLabel?.textColor = UIColor.label
}


}

Well, I could change this code

cell.accessoryType = .disclosureIndicator

to this

 let disclosureIndicatorTapped = UIImageView()
        disclosureIndicatorTapped.image = UIImage(systemName: "chevron.forward") // When tapped automatic to "Chevron.down"
        cell.accessoryView = disclosureIndicatorTapped

Any idea how to get Expandable Cells in UITableView with Swift, without Header or Footer needed?

Thanks!

CodePudding user response:

You can add a Bool "expanded" property to your Object.

In numberOfRowsInSection, if expanded is True, return the count of items in seactionObjection, else return 1.

Then, in didSelectRowAt, if it's the first row in a section, toggle the expanded property of that section's Object, and reload the section.

Here's a modified version of your controller class:

class HelpViewController: UIViewController, UITableViewDelegate, UITableViewDataSource {
    
    struct Object {
        var seactionName: String!
        var expanded: Bool!
        var seactionObjection: [String]!
        var footerName: String!
    }
    
    var objectArray = [Object]()
    
    var TableView = UITableView()
    
    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view.
        
        
        objectArray = [
            Object(seactionName: "Header 1",
                   expanded: false,
                   seactionObjection: ["Expandable Cell 1", "One Row 1", "Two Row 1"],
                   footerName: "Footer 1"),
            
            Object(seactionName: "Header 2",
                   expanded: false,
                   seactionObjection: ["Expandable Cell 2", "One Row 2", "Two Row 2"],
                   footerName: "Footer 2"),
            
            Object(seactionName: "Header 3",
                   expanded: false,
                   seactionObjection: ["Expandable Cell 3", "One Row 3", "Two Row 3"],
                   footerName: "Footer 3"),
            

            // copy and paste new cells
        ]
        
        title = "Help Center"
        
        view.backgroundColor = UIColor.quaternarySystemFill
        
        TableView.frame = view.bounds
        
        TableView = UITableView(frame: self.view.bounds, style: UITableView.Style.insetGrouped)
        TableView.showsVerticalScrollIndicator = true
        TableView.indicatorStyle = .default
        TableView.register(SliceCell.self, forCellReuseIdentifier: "Slice List")
        
        TableView.delegate = self
        TableView.dataSource = self
        
        view.addSubview(TableView)
    }
    
    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        // if section is expanded
        //  return count of seactionObjection
        // else
        //  return 1
        return objectArray[section].expanded ? objectArray[section].seactionObjection.count : 1
    }
    
    func numberOfSections(in tableView: UITableView) -> Int {
        return objectArray.count
    }
    
    func tableView(_ tableView: UITableView, titleForHeaderInSection section: Int) -> String? {
        return objectArray[section].seactionName
    }
    
    func tableView(_ tableView: UITableView, titleForFooterInSection section: Int) -> String? {
        return objectArray[section].footerName
    }
    
    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCell(withIdentifier: "Slice List") as! SliceCell
        
        cell.backgroundColor = .secondarySystemGroupedBackground
        cell.textLabel?.text = objectArray[indexPath.section].seactionObjection[indexPath.row]
        cell.textLabel?.numberOfLines = 0
        
        return cell
    }
    
    func tableView(_ tableView: UITableView, willDisplayHeaderView view: UIView, forSection section: Int){
        view.tintColor = .clear
        let header = view as! UITableViewHeaderFooterView
        header.textLabel?.textColor = UIColor.label
    }
    
    func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
        if indexPath.row == 0 {
            objectArray[indexPath.section].expanded.toggle()
            tableView.reloadSections([indexPath.section], with: .automatic)
        } else {
            // do something else on row selection
        }
    }
    
}
  • Related