I have a UITableViewCell
and I am adding xib
in cellForRowIndexPath
method. It works fine until I update the model and call reloadData on UITableView
. The cell is showing new data on top of the old data, I can see the label on the old label text.
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath)
let customView:CustomView = UIView.fromNib()
userView.frame = CGRect(x: 10, y: y, width: Int(self.tableView.bounds.size.width-50), height: 50)
userView.label.text = data[indexPath.row]
cell.addSubview(customView:)
Any guesses why this could happen?
The quick answer is this: since cells are reused when dequeued, you are adding a new CustomView
to a cell that already had a CustomView
added when dequeued previously.
One way you could handle this is to remove any existing CustomView
from the hierarchy before creating a new one and adding it. To do this you could add a recognizable tag to the view each time, and then look for a view with that same tag to remove during your dequeue process, like this:
//Remove existing view, if it exists
if let existingView = cell.viewWithTag(999) {
//A view was found - so remove it.
existingView.removeFromSuperview()
}
let customView: CustomView = UIView.fromNib()
//Set a tag so it can be removed in the future
customView.tag = 999
customView.frame = CGRect(x: 10, y: y, width: Int(self.tableView.bounds.size.width-50), height: 50)
customView.label.text = data[indexPath.row]
cell.addSubview(customView)
To me this feels like overkill, as it seems you should just add your customView to a custom UICollectionViewCell
so you aren't essentially creating a custom cell on the fly, but that is just me. If you did this you could simply dequeue your custom cell and set the text on the label without having to add more views to the hierarchy all the time.