Reputation: 175
i have a tableview with a custom cell which includes a label and image, on load its fine and all cells are displayed correctly.
However when i scroll down as there are over 200 cells, when i scroll back up, the cells data in the cells change - so for example - i could have the correct image but wrong label or wrong image but correct label. I am not sure what i am doing wrong.
Here is my code so far:
import UIKit
class SearchTableViewCell: UITableViewCell {
static let identifier = "SearchTableViewCell"
@IBOutlet var loader: UIActivityIndicatorView!
@IBOutlet var nameLabel: UILabel!
@IBOutlet var addressLabel: UILabel!
@IBOutlet var locationImageView: UIImageView!
var currentIndexPath: IndexPath?
override func awakeFromNib() {
super.awakeFromNib()
nameLabel.font = UIFont(name: Settings.shared.MAIN_APP_FONT_BOLD, size: 25)
nameLabel.textColor = .white
nameLabel.numberOfLines = 1
addressLabel.font = UIFont(name: Settings.shared.MAIN_APP_FONT_BOLD, size: 15)
addressLabel.textColor = .white
addressLabel.numberOfLines = 0
locationImageView.clipsToBounds = true
locationImageView.layer.cornerRadius = 8.0
locationImageView.contentMode = .scaleAspectFill
}
func configure(with urlString: String, name: String, address: String, station: String) {
loader.startAnimating()
loader.isHidden = false
guard let url = URL(string: urlString) else {
return
}
let task = URLSession.shared.dataTask(with: url) { [weak self] data, _, error in
guard let data = data, error == nil else {
return
}
let locationImage = UIImage(data: data)
DispatchQueue.main.async {
self?.nameLabel.text = name
self?.addressLabel.text = address
self?.locationImageView.image = locationImage
self?.loader.stopAnimating()
self?.loader.isHidden = true
}
}
task.resume()
}
static func nib() -> UINib {
return UINib(nibName: "SearchTableViewCell", bundle: nil)
}
override func setSelected(_ selected: Bool, animated: Bool) {
super.setSelected(selected, animated: animated)
}
override func prepareForReuse() {
super.prepareForReuse()
nameLabel.text = nil
locationImageView.image = nil
currentIndexPath = nil
}
}
Upvotes: 0
Views: 483
Reputation: 23701
You are loading the contents of the cell asynchronously. The UITableView
will reuse the cells. So suppose:
Now the cell you had in Step 1 is the same as the new cell that was just put somewhere else in the table, but it has the wrong content because your asynchronous load finished after the cell was reused.
The cell is just for displaying information... it shouldn't be loading data. The Data Source is the guy that loads data. You need to rethink your design and change the place where you load data.
Upvotes: 1