Expand and Collapse Tableview Cells

Expand and Collapse tableview cells

If you want the cell to get physically bigger, then where you have your store IndexPath, in heightForRow: use:

override func tableView(tableView: UITableView, heightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat {
if selectedIndexPath == indexPath {
return 230 + extraHeight
}
return 230.0
}

Then when you want to expand one in the didSelectRow:

selectedIndexPath = indexPath
tableView.beginUpdates
tableView.endUpdates

Edit

This will make the cells animate themselves getting bigger, you dont need the extra animation blocks in the cell.

Edit 2

 override func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
if(selectedIndexPath == indexPath) {
selectedIndexPath = nil

if let cell = tableView.cellForRowAtIndexPath(indexPath) as? MyTicketsTableViewCell {
cell.collapse()
}
if let cell = tableView.cellForRowAtIndexPath(NSIndexPath(forRow:indexPath.row+1, section: indexPath.section) as? MyTicketsTableViewCell {
cell.collapse()
}
} else {
selectedIndexPath = indexPath

if let cell = tableView.cellForRowAtIndexPath(indexPath) as? MyTicketsTableViewCell {
cell.expand()
}

if let cell = tableView.cellForRowAtIndexPath(NSIndexPath(forRow:indexPath.row+1, section: indexPath.section) as? MyTicketsTableViewCell {
cell.expand()
}
}

tableView.beginUpdates()
tableView.endUpdates()
}

How to expand and collapse tableview cells with dynamic height programmatically?

You can use UIStackView for expand and collapse tableview. You can hide and show the description label when tableview cell is selected.

class ViewController: UIViewController {
var tableView: UITableView = {
let tv = UITableView(frame: .zero)
tv.register(CustomCell.self, forCellReuseIdentifier: "CustomCell")
tv.translatesAutoresizingMaskIntoConstraints = false
tv.rowHeight = UITableView.automaticDimension
tv.estimatedRowHeight = 100.0
tv.estimatedSectionHeaderHeight = 0
tv.estimatedSectionFooterHeight = 0
tv.showsVerticalScrollIndicator = false
tv.tableFooterView = UIView()
tv.alwaysBounceVertical = true
tv.decelerationRate = .fast
tv.bounces = false
return tv
}()
var selectedCell:IndexPath?

override func viewDidLoad() {
super.viewDidLoad()
self.view.addSubview(tableView)
tableView.dataSource = self
tableView.delegate = self
self.view.addConstraints(NSLayoutConstraint.constraints(withVisualFormat: "V:|[tableView]|", options: [], metrics: nil, views: ["tableView":tableView]))
self.view.addConstraints(NSLayoutConstraint.constraints(withVisualFormat: "H:|[tableView]|", options: [], metrics: nil, views: ["tableView":tableView]))
}

}
extension ViewController: UITableViewDataSource, UITableViewDelegate {
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return 10
}

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "CustomCell") as? CustomCell ?? CustomCell()
if let selectedCell = selectedCell, selectedCell == indexPath {
cell.descriptionLabel.isHidden = false
} else {
cell.descriptionLabel.isHidden = true
}
return cell
}
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
selectedCell = indexPath
tableView.reloadData()
}
func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
return UITableView.automaticDimension
}
func tableView(_ tableView: UITableView, estimatedHeightForRowAt indexPath: IndexPath) -> CGFloat {
return 100
}

}

class CustomCell: UITableViewCell {

let stackView = UIStackView()
let wordLabel = UILabel()
let descriptionLabel = UILabel()

override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) {
super.init(style: style, reuseIdentifier: reuseIdentifier)
setupLabels()
}

required public init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
setupLabels()
}

func setupLabels() {

selectionStyle = .none

stackView.axis = .vertical
stackView.distribution = .equalSpacing
stackView.spacing = 5
stackView.alignment = .fill
stackView.translatesAutoresizingMaskIntoConstraints = false
self.contentView.addSubview(stackView)

wordLabel.translatesAutoresizingMaskIntoConstraints = false
wordLabel.text = "Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lor"
wordLabel.numberOfLines = 0
wordLabel.lineBreakMode = .byWordWrapping
stackView.addArrangedSubview(wordLabel)

descriptionLabel.translatesAutoresizingMaskIntoConstraints = false
descriptionLabel.text = "It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s with the release of Letraset sheets containing Lorem Ipsum passages, and more recently with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum."
descriptionLabel.numberOfLines = 0
descriptionLabel.lineBreakMode = .byWordWrapping
stackView.addArrangedSubview(descriptionLabel)

wordLabel.heightAnchor.constraint(greaterThanOrEqualToConstant: 30).isActive = true
descriptionLabel.heightAnchor.constraint(greaterThanOrEqualToConstant: 30).isActive = true

stackView.leadingAnchor.constraint(equalTo: self.contentView.layoutMarginsGuide.leadingAnchor,constant: 10).isActive = true
stackView.topAnchor.constraint(equalTo: self.contentView.layoutMarginsGuide.topAnchor,constant: 10).isActive = true
stackView.trailingAnchor.constraint(equalTo: self.contentView.layoutMarginsGuide.trailingAnchor,constant: 10).isActive = true
stackView.bottomAnchor.constraint(equalTo: self.contentView.layoutMarginsGuide.bottomAnchor,constant: 10).isActive = true

}
}

TableView expand and collapse cells in Swift

You need to reset them all to false then toggle the current state of the clicked section

let toSet = !sections[indexPath.section].isOpened
sections.forEach {
$0.isOpened = false
}
sections[indexPath.section].isOpened = toSet
tableView.reloadData()

how to make tableview cells expand and collapse

Try reloading cell on didSelectRow inside beginUpdates and endUpdates.
Have a look at sample code below. Choose row realod animation as per your need.

override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
switch(indexPath) {
case [2,0]:
isPickerHidden = !isPickerHidden

dueDateLabel.textColor = isPickerHidden ? .black : tableView.tintColor

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

default: break
}
}

How to reload selected cell in particular section for expand/collapse in tableview Swift

If you store section and row independently in separate arrays, your algorithm will fail.
The reason is that both are dependent:
Think of three expanded cells (row:1, section:1), (row:2, section:1), (row:3, section:2)

Now what happens for the cell (row:3, section:1)?
The row-array contains the value "3", and the section-array contains value "1", therefore it will be considered as expanded.

Therefore, you need to store the index path as a whole - see the sample code:

var expanded:[IndexPath] = []

expanded.append(IndexPath(row:1, section:1))
expanded.append(IndexPath(row:2, section:1))
expanded.append(IndexPath(row:3, section:2))

let checkPath = IndexPath(row:3, section:1)
if (expanded.contains(checkPath)) {
print ("is expanded")
} else {
print ("collapsed")
}

Update

So in your button handle, you'll do the following:

@IBAction moreButtonTapped(_ sender: Any) {

if(expanded.contains(indexPath)) {
expanded.removeAll { (checkPath) -> Bool in
return checkPath == indexPath
}
} else {
expanded.append(indexPath)
}
entriesTableView.beginUpdates()
entriesTableView.reloadRows(at: [indexPath], with: .none)
entriesTableView.endUpdates()
}

Unable to Expand and Collapse TableViewCell in Swift

Add a property to your activeCategories array 's model

var isExpanded = true

Then inside numberOfRowsInSection

guard let item = self.activeCategories?[section] else { return 0 }
return item.isExpanded ? (item.sub_categories?.count ?? 0) : 0

Then play with isExpanded and refresh the table

Edit

Inside viewForHeaderInSection

 let header = tableView.dequeueReusableCell(withIdentifier: "CategoryTableCell") as! CategoryTableCell 
button.tag = section

Then inside action

@objc headerClicked(_ sender:UIButton) {
let section = sender.tag
guard let item = self.activeCategories?[section] else { return 0 }
item.isExpanded.toggle()
tableView.reloadData()
}

Expand the only tapped cell and collapse other cells

You need to collapse all cells and change the current clicked one state , then reload all the table

func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
let current = datasource[indexPath.row].expanded
datasource.forEach { $0.expanded = false }
let content = datasource[indexPath.row]
content.expanded = !current
tableView.reloadData()
}


Related Topics



Leave a reply



Submit