简体   繁体   中英

How to expand cell when button inside cell is pressed?

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM