Reputation: 2457
I have a typical UITableView
with custom cells. All cells are of the same type - one UIStackView which contains the views of the same type but varies their count.
Tried to use one cell for all - it is slow to delete-add inner views.
Tried to create different cells for different count of subviews:
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let row = rows[indexPath.row]
let CellIdentifier = "CellIdentifier\(row.subrows.count)"
var cell = tableView.dequeueReusableCell(withIdentifier: CellIdentifier) as? CustomCell
if cell == nil {
tableView.register(UINib(nibName: "WTRemindersTableViewCell", bundle: nil), forCellReuseIdentifier: CellIdentifier)
cell = tableView.dequeueReusableCell(withIdentifier: CellIdentifier) as? CustomCell
for _ in row.subrows {
let v = Bundle.main.loadNibNamed("CustomInnerView", owner: self, options: nil)?.first as! WTRemindersCellLineView
cell!.stackView.addArrangedSubview(v)
}
}
return cell!
}
but it seems it registers just a cell without of subviews and it has no sense to use different cell identifiers (because each time you need to add stackview subviews manually).
How to solve this issue?
Edited
Added code for cell
class CustomCell: UITableViewCell {
@IBOutlet var boxView: UIView!
@IBOutlet var imgView: UIImageView!
@IBOutlet var lblTitle: UILabel!
@IBOutlet var lblSubtitle: UILabel!
@IBOutlet var dashedView: WTDashedView!
@IBOutlet var stackView: UIStackView!
weak var delegate: CustomCellDelegate?
var index: Int!
lazy var onceDraw: () = {
boxView.layer.applySketchShadow()
}()
override func awakeFromNib() {
super.awakeFromNib()
boxView.layer.cornerRadius = 19
imgView.layer.cornerRadius = 12
}
override func draw(_ rect: CGRect) {
super.draw(rect)
_=onceDraw
}
@IBAction func btnDotsClicked(_ sender: Any) {
delegate?.btnDotsClicked(at: index)
}
}
Upvotes: 0
Views: 936
Reputation: 5073
First, you should register your cell in viewDidLoad
. Note I'm not sure what your nib is named, so make sure to adjust it for your needs.
override func viewDidLoad() {
super.viewDidLoad()
tableView.register(
UINib(nibName: "CustomCell", bundle: nil),
forCellReuseIdentifier: "CustomCell"
)
}
It's hard to tell what you were doing in your cellForRowAt
method but this will do the trick. Cells are reused so make sure that you remove any remaining arranged subviews. You shouldn't have any performance issues if you do it this way:
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "CustomCell", for: indexPath) as! CustomCell
let row = rows[indexPath.row]
cell.stackView.arrangedSubviews.forEach { $0.removeFromSuperview() }
for _ in row.subrows {
cell.stackView.addArrangedSubview(cellView())
}
return cell
}
This is just a little helper method to instantiate your view:
func cellView() -> WTRemindersCellLineView {
return Bundle.main.loadNibNamed(
"WTRemindersCellLineView", owner: nil, options: nil
)?.first as! WTRemindersCellLineView
}
Upvotes: 0