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
}
}
}
