UITableView滚动时如何维护UITableViewCell状态?

时间:2018-12-22 07:36:27

标签: ios swift uitableview

我有一个关于扩展UITableViewCell的问题。
当我单击UIButton时,标题为“显示更多”,并且正在成功扩展。
然后,当我滚动UITableView时,我看到一种情况,那就是我没有单击的其他单元格,UIButton也展开了。
有什么好主意要解决这个问题吗?
谢谢。

class ViewController: UIViewController {

let tableView = UITableView()
let cellWithButton = "cellWithButton"
var isExpand: Bool = false
var expandIndexs: [IndexPath] = []
let text = "If you read and listen to two articles every day, your reading and listening skills can immm If you read and listen to two articles every day, your reading and listening skills can immm If you read and listen to two articles every day, your reading and listening skills can immm If you read and listen to two articles every day, your reading and listening skills can immm If you read and listen to two articles every day, your reading and listening skills can immm"

override func viewDidLoad() {
    super.viewDidLoad()

    tableView.delegate = self
    tableView.dataSource = self
    tableView.allowsSelection = false
    tableView.separatorInset = .zero
    tableView.estimatedRowHeight = 44
    tableView.rowHeight = UITableViewAutomaticDimension
    tableView.register(WithButtonTableViewCell.self, forCellReuseIdentifier: cellWithButton)


    self.view.addSubview(tableView)

    tableView.snp.makeConstraints { (make) in
        make.top.left.right.bottom.equalToSuperview()
    }
}

@objc func btnPressed(sender: UIButton) {

    let indexPath = IndexPath(row: sender.tag, section: 0)

    if self.isExpand == false {

        self.isExpand = true

        self.expandIndexs.append(indexPath)

    } else {
        self.isExpand = false

        let index = self.expandIndexs.index(of: indexPath)

        if let index = index {
            self.expandIndexs.remove(at: index)
        }
    }

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

}
}

extension ViewController: UITableViewDelegate, UITableViewDataSource {

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

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {

    let cell = tableView.dequeueReusableCell(withIdentifier: cellWithButton, for: indexPath) as! WithButtonTableViewCell

    if self.expandIndexs.contains(indexPath) {
        cell.cellIsExpand = self.isExpand
    }
    cell.titleLabel.text = text
    cell.expandButton.addTarget(self, action: #selector(btnPressed), for: .touchUpInside)
    cell.expandButton.tag = indexPath.row
    cell.layoutIfNeeded()

    return cell
}
}


class WithButtonTableViewCell: UITableViewCell {

var cellIsExpand: Bool = false

let titleLabel: UILabel = { () -> UILabel in
    let ui = UILabel()
    ui.textColor = UIColor.black
    return ui
}()

let expandButton: UIButton = { () -> UIButton in
    let ui = UIButton()
    ui.setTitleColor(UIColor.blue, for: .normal)
    return ui
}()

override func awakeFromNib() {
    super.awakeFromNib()
    // Initialization code
}

override func setSelected(_ selected: Bool, animated: Bool) {
    super.setSelected(selected, animated: animated)

    // Configure the view for the selected state
}

override init(style: UITableViewCellStyle, reuseIdentifier: String?) {
    super.init(style: style, reuseIdentifier: reuseIdentifier)

    loadUI()
    loadLayout()
}

required init?(coder aDecoder: NSCoder) {
    fatalError("init(coder:) has not been implemented")

}

override func layoutIfNeeded() {
    super.layoutIfNeeded()

    if cellIsExpand == true {
        titleLabel.numberOfLines = 0
        expandButton.setTitle("Close.", for: .normal)
    }else{
        titleLabel.numberOfLines = 2
        expandButton.setTitle("Show More.", for: .normal)
    }
}

func loadUI() {

    self.addSubview(titleLabel)
    self.addSubview(expandButton)
}

func loadLayout() {

    titleLabel.snp.makeConstraints { (make) in
        make.top.left.equalTo(15)
        make.right.equalTo(-15)
    }

    expandButton.snp.makeConstraints { (make) in
        make.top.equalTo(titleLabel.snp.bottom).offset(10)
        make.left.equalTo(10)
        make.right.equalTo(-15)
        make.bottom.equalTo(-15)            
    }
}
}

image here

2 个答案:

答案 0 :(得分:1)

您应该为isExpand使用boolean数组,并在cellForRow中检查它是否确实更改了row的高度。

首先make数组:

var expandingStateArray = [false,false,false,false,false,false,false,false,false,false]

然后在cellForRows中检查每个单元格的状态:

    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {

        let cell = tableView.dequeueReusableCell(withIdentifier: cellWithButton, for: indexPath) as! WithButtonTableViewCell

if expandingStateArray[indexPath.row] {
            titleLabel.numberOfLines = 0
            expandButton.setTitle("Close.", for: .normal)
        }else{
            titleLabel.numberOfLines = 2
            expandButton.setTitle("Show More.", for: .normal)
        }
        cell.titleLabel.text = text
        cell.expandButton.addTarget(self, action: #selector(btnPressed), for: .touchUpInside)
        cell.expandButton.tag = indexPath.row
        cell.layoutIfNeeded()


        return cell
    }
    }

然后在按钮的目标方法中编写以下内容:

@objc func btnPressed(sender: UIButton) {

let indexPath = IndexPath(row: sender.tag, section: 0)

expandingStateArray[sender.tag] = !expandingStateArray[sender.tag]

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

}
}

答案 1 :(得分:0)

在分配/不分配其layoutIfNeeded()变量后,只需在单元格上调用cellIsExpand

if self.expandIndexs.contains(indexPath) {
    cell.cellIsExpand = self.isExpand
}
cell.layoutIfNeeded()