// resizing table view cells on data change
import UIKit
struct MyDataStruct {
var title: String = ""
var tapCount: Int = 0
}
class SimpleCell: UITableViewCell {
var callback: ((Int, UITableViewCell)->())?
let theLabel: UILabel = {
let v = UILabel()
v.numberOfLines = 0
v.backgroundColor = .yellow
return v
}()
let btn: UIButton = {
let v = UIButton()
v.backgroundColor = .systemRed
return v
}()
private var title: String = ""
private var tapCount: Int = 0
override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) {
super.init(style: style, reuseIdentifier: reuseIdentifier)
commonInit()
}
required init?(coder: NSCoder) {
super.init(coder: coder)
commonInit()
}
func setData(_ d: MyDataStruct) -> Void {
title = d.title
tapCount = d.tapCount
theLabel.text = title + " Taps: \(tapCount)"
}
func commonInit() -> Void {
[theLabel, btn].forEach { v in
v.translatesAutoresizingMaskIntoConstraints = false
contentView.addSubview(v)
}
let g = contentView.layoutMarginsGuide
NSLayoutConstraint.activate([
theLabel.topAnchor.constraint(equalTo: g.topAnchor),
theLabel.leadingAnchor.constraint(equalTo: g.leadingAnchor),
theLabel.bottomAnchor.constraint(lessThanOrEqualTo: g.bottomAnchor),
btn.topAnchor.constraint(equalTo: g.topAnchor),
btn.trailingAnchor.constraint(equalTo: g.trailingAnchor),
btn.bottomAnchor.constraint(lessThanOrEqualTo: g.bottomAnchor),
btn.widthAnchor.constraint(equalToConstant: 100.0),
btn.leadingAnchor.constraint(equalTo: theLabel.trailingAnchor, constant: 8.0),
])
btn.setTitle("Tap Me", for: [])
btn.addTarget(self, action: #selector(gotTap(_:)), for: .touchUpInside)
}
@objc func gotTap(_ sender: Any) {
tapCount += 1
theLabel.text = title + " Taps: \(tapCount)"
callback?(tapCount, self)
}
}
class RowSizingTableViewController: UITableViewController {
var myData: [MyDataStruct] = []
override func viewDidLoad() {
super.viewDidLoad()
for i in 0..<20 {
let t = MyDataStruct(title: "Row: \(i)", tapCount: 0)
myData.append(t)
}
tableView.register(SimpleCell.self, forCellReuseIdentifier: "cell")
}
// MARK: - Table view data source
override func numberOfSections(in tableView: UITableView) -> Int {
return 1
}
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return myData.count
}
override func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
print(#function, indexPath, myData[indexPath.row])
return CGFloat(60 + (myData[indexPath.row].tapCount * 20))
}
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath) as! SimpleCell
cell.setData(myData[indexPath.row])
cell.callback = { [weak self] n, c in
guard let self = self,
let pth = self.tableView.indexPath(for: c)
else { return }
// update data
self.myData[pth.row].tapCount = n
// both
// beginUpdates() / endUpdates()
// and
// performBatchUpdates()
// seem to work fine...
self.tableView.beginUpdates()
self.tableView.endUpdates()
//self.tableView.performBatchUpdates(nil, completion: nil)
}
return cell
}
}
Comments
0 B
|👍
/👎
0 B
|👍
/👎
0 B
|👍
/👎