所以伙计们,我曾经遇到Massive View Controller
问题,特别是在使用UITableView
时,现在我正在改变一个旧的应用程序更加模态。之前,我曾经将整个单元格设置为cellForRowAt indexPath
。设置标签,下载图像等。
现在我正在使用正确的方法设置UITableViewCell
子类。但我遇到了问题,重新使用单元格,在更新/下载新图片的同时离开旧图片,我认为我修复了,但我也注意到它恰好将错误的图像放在错误的单元格然后在进行快速滚动时更新为正确的...
在我做这样的事情之前,确保图像在正确的单元格中更新。就像这样从视图控制器设置整个单元格......
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "Identifier")
cell.title = "Cool title"
imageLoader.obtainImageWithPath(imagePath: viewModel.image) { (image) in
// Before assigning the image, check whether the current cell is visible for ensuring that it's right cell
if let updateCell = tableView.cellForRow(at: indexPath) {
updateCell.imageView.image = image
}
}
return cell
}
现在我几乎只有viewcontroller
...
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell : RestCell = self.tableView.dequeueReusableCell(withIdentifier: "Cell", for: indexPath) as! RestCell
// Pass data to Cell :) clean the mess at the View Controller ;)
cell.restData = items[indexPath.row]
return cell
}
UITableViewCell子类我有这个。
class RestCell: UITableViewCell {
@IBOutlet var img : UIImageView!
@IBOutlet var lbl : UILabel!
@IBOutlet var lbl_tipocomida: UILabel!
@IBOutlet var lbl_provincia: UILabel!
@IBOutlet var img_orderonline: UIImageView!
@IBOutlet var img_open: UIImageView!
@IBOutlet var imgalldelivery: UIImageView!
@IBOutlet var img_reservasonline: UIImageView!
// get data and update.
var restData: RestsModel! {
didSet {
// default img early placeholder set. Eliminates showing old pic in cell reuse
self.img.image = UIImage(named: "60x60placeholder.png")
// Update all values func
updateUI()
}
}
override func awakeFromNib() {
super.awakeFromNib()
// Default image placeholder
//self.img.image = UIImage(named: "60x60placeholder.png")
}
// required init.
required init(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)!
// Color of selected.
let myCustomSelectionColorView = UIView()
myCustomSelectionColorView.backgroundColor = UIColor(red: 234.0/255.0, green: 46.0/255.0, blue: 73.0/255.0, alpha: 0.1) //UIColor(netHex:0xFFFF434)
selectedBackgroundView = myCustomSelectionColorView
}
fileprivate func updateUI() {
if (self.restData.image != nil && self.restData.image != "") {
ImageLoader.sharedLoader.imageForUrl(urlString:self.restData.image, completionHandler:{(image: UIImage?, url: String) in
self.img.contentMode = UIViewContentMode.scaleAspectFit
self.img.image = image
})
} else {
self.img.image = UIImage(named: "60x60placeholder.png")
}
self.lbl.text = restData.name as String
self.lbl_provincia.text = restData.provincia as String
self.lbl_tipocomida.text = restData.tipocomida as String
// check if has alldelivery enabled, show Alldelivery logo
if( self.restData.reservaonline == "1") {
self.img_reservasonline.isHidden = false
self.img_reservasonline.image = UIImage(named: "icon_reserva_on")
} else {
self.img_reservasonline.isHidden = true
self.img_reservasonline.image = UIImage(named: "icon_reserva_off")
}
// check if has orderonline, show ordeonline text
if ( self.restData.orderonline == "1") {
self.img_orderonline.isHidden = false
} else {
self.img_orderonline.isHidden = true
}
// check if has schedule, display if open or close
if (self.restData.hasSchedule == true) {
if ( self.restData.openNow == true) {
self.img_open.image = UIImage(named:"icon_open")
} else {
self.img_open.image = UIImage(named:"icon_close")
}
self.img_open.isHidden = false
} else {
self.img_open.isHidden = true
}
}
}
我在UITableViewVCell
子类的图像上调用下载并将其设置在那里。如何确保图像仅设置为正确的单元格
答案 0 :(得分:2)
由于竞争条件而发生这种情况(这很常见)
根据您当前的解决方案,我会这样做:
self.myUIImage.image = nil
之类的操作。您可能需要检查一些类似的问题:
答案 1 :(得分:1)
我建议您使用第三方库来加载包含Kingfisher
等网址的图片。它将处理缓存并取消加载。
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let data = dataSource[indexPath.row]
let cell = tableView.dequeueReusableCell(withIdentifier: "Identifier") as! ACell
cell.update(data)
return cell
}
细胞看起来像这样。
import Kingfisher
class ACell: UITableViewCell {
@IBOutlet fileprivate weak var backgroundImageView: UIImageView!
fileprivate func reset() {
backgroundImageView.image = nil
}
func update(_ data: ATypeOfData) {
reset()
let resource = ImageResource(downloadURL: url)
backgroundImageView.kf.setImage(with: resource)
}
}
你失败的原因是你误解了重复使用细胞。
let updateCell = tableView.cellForRow(at: indexPath)
updateCell
可以是与您要使用的单元格不同的单元格。它可以只是一个重用的随机单元格。如果您确实想要跟踪单元格,则需要设置属性并检查cellForRowAt
中的属性是否与图像加载闭包中的属性相同。我真的建议你使用我附带的模式。