I'm newer in xcode and swift and i found a guide for expand cell when the entire cell is pressed. Now i wanna expand the cell when the button inside the cell is pressed.
I have this in my view controller :
//datasource
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
if tableView.tag == 100 {
return nameArr.count
}else{
return prova.count
}
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
if tableView.tag == 100 {
let cell = tableView.dequeueReusableCell(withIdentifier: "MainTableViewCell") as! MainTableViewCell
cell.lblName.text = nameArr[indexPath.row]
cell.expand.tag = indexPath.row
return cell
}else{
tableView.estimatedRowHeight = 60
tableView.rowHeight = UITableView.automaticDimension
let cell = tableView.dequeueReusableCell(withIdentifier: "InsideTableViewCell") as! InsideTableViewCell
cell.lblInsideName.text = prova[indexPath.row]
return cell
}
}
func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
//se la cella è selezionata e deve essere tirata ancora giù ritorna 243 che sarebbe il valore della cella + l'immagine dentro da mostrare
if selectedIndex == indexPath.row && isCollapsed == true && tableView.tag == 100 {
return 375
}else {
//altrimenti se è gia collassata e ripremiamo sulla cella ritorna 50 e quindi richiude la cella
return 96
}
}
//delegate
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
tableView.deselectRow(at: indexPath, animated: true)
if selectedIndex == indexPath.row {
if self.isCollapsed == false {
self.isCollapsed = true
}else{
self.isCollapsed = false
}
}else{
self.isCollapsed = true
}
self.selectedIndex = indexPath.row
//tableView.reloadRows(at: [indexPath], with: .automatic)
tableView.beginUpdates()
tableView.endUpdates()
}
But i don't know ho to do that.
In my viewController now i have this variable :
var selectedIndex = -1 //tell me which cell i pressed
var isCollapsed = false // tell if the cell is already collapsed
You should update the table view after changing the height: tableView.reloadData()
.
You can do it by sending info about that action to the view controller using delegates.
1) You should save a state of your cells. You can store it in the cell model:
class YourCellModel {
var isExpanded = false
}
2) You should create a delegate protocol:
protocol YourCellDelegate: AnyObject {
func buttonPressed()
}
3) Add properties for the cell delegate and the cell model. Also you should add a function buttonPressed
:
class YourCell: UITableViewCell {
weak var delegate: YourCellDelegate?
var model: YourCellModel?
//...
@IBAction func buttonPressed() {
model?.isExpanded = true
delegate?.buttonPressed()
}
}
4) You should store cell models in the view controller: {
class YourViewController: UIViewController {
var cellModels: [YourCellModel] = []
//...
override func viewDidLoad() {
super.viewDidLoad()
cellModels = Array(repeating: YourCellModel(), count: <count of cells, maybe it is a prova.count>)
}
}
5) Setup cell models and delegates to the cells in cellForItem
:
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let model = cellModels[indexPath.row]
if tableView.tag == 100 {
let cell = tableView.dequeueReusableCell(withIdentifier: "MainTableViewCell") as! MainTableViewCell
cell.lblName.text = nameArr[indexPath.row]
cell.expand.tag = indexPath.row
cell.model = model
cell.delegate = self
return cell
} else {
tableView.estimatedRowHeight = 60
tableView.rowHeight = UITableView.automaticDimension
let cell = tableView.dequeueReusableCell(withIdentifier: "InsideTableViewCell") as! InsideTableViewCell
cell.lblInsideName.text = prova[indexPath.row]
cell.model = model
cell.delegate = self
return cell
}
}
6) Update heightForItem
:
func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
let model = cellModels[indexPath.row]
if model.isExpanded {
return 375
} else {
return 96
}
}
7) Your view controller should implement YourCellDelegate
:
extension YourViewController: YourCellDelegate {
func buttonPressed() {
tableView.reloadData()
}
}
Modify the data source to change it
And of course the data source can be more complex it can be an object that contains whether or not to open the property
let nameArr:[Bool] = [false, false, false]
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
self.nameArr[indexPath.row] = !self.nameArr[indexPath.row]
tableView.reloadRows(at: [indexPath], with: .none)
}
func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
let isshow = self.nameArr[indexPath.row]
if isshow {
return 375
} else {
return 69
}
}
You can define a clouser in cell and call it when you press the button in your cell
in your cell define:
var buttonClicked: (() -> Void)?
in your cell button call this clouser
func buttonPressAction() {
buttonClicked?()
}
in your cellForRow method change it like this:
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
if tableView.tag == 100 {
let cell = tableView.dequeueReusableCell(withIdentifier: "MainTableViewCell") as! MainTableViewCell
cell.buttonClicked = { [weak self] in
if self.isCollapsed == false {
self.isCollapsed = true
} else{
self.isCollapsed = false
}
}else{
self.isCollapsed = true
}
}
}
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.