我正在关注this教程如何避免UITableView
的滞后,但人口数据效果不佳。有时显示错误的数据并且不再更改,或者显示错误然后切换到正确的数据。
我怎么能解决这个问题?
这是教程中需要的课程
class SerialOperationQueue: OperationQueue
{
override init()
{
super.init()
maxConcurrentOperationCount = 1
}
}
然后在VehicleCell
课程中我有
let queue = SerialOperationQueue()
在模型方法中,从教程中可以看出:
模板:
func setSomething(vehicle: VehicleModel) -> String {
Thread.sleep(forTimeInterval: 0.01)
return "some string from model"
}
在UITableViewDataSource
我有
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
return vehiclesTableView.dequeueReusableCell(withIdentifier: "vehicleCell", for: indexPath) as! VehiclesCell
}
和willDisplay
func tableView(_ tableView: UITableView, willDisplay cell: UITableViewCell, forRowAt indexPath: IndexPath) {
if let cell = cell as? VehiclesCell {
configureCell(cell: cell, indexPath: indexPath)
}
cell.alpha = 0
cell.layer.transform = CATransform3DMakeScale(0.1, 0.1, 1)
cell.layoutIfNeeded()
cell.layer.removeAllAnimations()
UIView.animate(withDuration: 0.3, delay: 0, options: .curveEaseOut, animations: {
cell.alpha = 1
cell.layer.transform = CATransform3DMakeScale(1, 1, 1)
cell.layoutIfNeeded()
})
}
private func configureCell(cell: VehiclesCell, indexPath: IndexPath) {
cell.queue.cancelAllOperations()
let operation: BlockOperation = BlockOperation()
operation.addExecutionBlock {
let vehicles = self.checkForVehicles(inSection: indexPath.section)
let vehicle = vehicles[indexPath.row]
let vehicleName = self.setVehicleName(vehicle: vehicle)
let driverName = self.setDriverName(vehicle: vehicle)
let topColor = self.setTopLineColor(vehicle: vehicle, colorView: cell.topColorView)
let vehicleImage = self.setVehicleImage(vehicle: vehicle)
let address = self.setAddress(vehicle: vehicle)
let engineStatus = self.setEngineStatus(vehicle: vehicle)
let hosStatus = self.setHosStatus(vehicle: vehicle)
let speed = self.setSpeed(vehicle: vehicle)
DispatchQueue.main.async {
if operation.isCancelled { return }
cell.vehicleNameLabel.text = vehicleName
cell.driverNameLabel.text = driverName
cell.topColorView = topColor
cell.vehicleImageView.image = vehicleImage
cell.localizationLabelView.text = address
cell.engineLabel.text = engineStatus
cell.hosStatusLabel.text = hosStatus
cell.speedValueLabel.text = speed
}
}
cell.queue.addOperation(operation)
}
有人能解释我这种行为吗?为什么单元格填充了错误的数据,然后当它们变得正确时,它们会切换。他们可能会保持这样状态而不会转换为良好的数据吗?
解决这个问题的最佳选择是什么?
提前致谢!
答案 0 :(得分:0)
问题是您没有覆盖VehicleCell
中的prepareForReuse
function。
由于单元格在UITableView
中被重用以获得更平滑的性能,因此它会重复使用tableView中的单元格,而不是每次需要新单元格时都创建新实例。
执行此操作时:
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
return vehiclesTableView.dequeueReusableCell(withIdentifier: "vehicleCell", for: indexPath) as! VehiclesCell
}
而不是创建新的单元格,您可以使用标识符对可重复使用的单元格进行出列。
因此,重要的是,您覆盖perpareForReuse
函数。查看您的VehicleCell界面,它应该如下所示:
override func prepareForReuse() {
super.prepareForReuse()
self.vehicleNameLabel.text = nil
self.driverNameLabel.text = nil
self.topColorView = nil
self.vehicleImageView.image = nil
self.localizationLabelView.text = nil
self.engineLabel.text = nil
self.hosStatusLabel.text = nil
self.speedValueLabel.text = nil
}
willDisplayCell
中的所有代码都是不需要的代码,什么不起作用,根本就没有意义。
修改强> 我喜欢configureCell方法,但不喜欢使用队列。所以我建议你做以下事情:
willDisplay
功能。configureCell
configureCell
致电cellForRowAt
,并在设置完成后返回```
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell: VehiclesCell = vehiclesTableView.dequeueReusableCell(withIdentifier: "vehicleCell", for: indexPath) as! VehiclesCell
self.configureCell(cell: cell, indexPath: indexPath)
return cell
}
private func configureCell(cell: VehiclesCell, indexPath: IndexPath) {
let vehicles = self.checkForVehicles(inSection: indexPath.section)
let vehicle = vehicles[indexPath.row]
let vehicleName = self.setVehicleName(vehicle: vehicle)
let driverName = self.setDriverName(vehicle: vehicle)
let topColor = self.setTopLineColor(vehicle: vehicle, colorView: cell.topColorView)
let vehicleImage = self.setVehicleImage(vehicle: vehicle)
let address = self.setAddress(vehicle: vehicle)
let engineStatus = self.setEngineStatus(vehicle: vehicle)
let hosStatus = self.setHosStatus(vehicle: vehicle)
let speed = self.setSpeed(vehicle: vehicle)
cell.vehicleNameLabel.text = vehicleName
cell.driverNameLabel.text = driverName
cell.topColorView = topColor
cell.vehicleImageView.image = vehicleImage
cell.localizationLabelView.text = address
cell.engineLabel.text = engineStatus
cell.hosStatusLabel.text = hosStatus
cell.speedValueLabel.text = speed
}
```