UITableView中的图像不断重新加载,错误的图像在快速滚动时会闪烁



应用程序有一个UITableView,它将动态图像加载到单元格中。在滚动时下载图像,并将其转换为UIImages。这些UIImages将在KingFisher的帮助下设置为ImageView。简单缓存机制已经实现,但图像在滚动时会闪烁,直到加载确切的图像。代码如下所述。

表格视图代码

extension EmployeeListViewController:UITableViewDelegate,UITableViewDataSource {

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {

let cell = tableView.dequeueReusableCell(withIdentifier: String(describing: EmployeeTableViewCell.self), for: indexPath) as! EmployeeTableViewCell
cell.onBindCell(management: (employeePresenter?.getManagementItem(position: indexPath.row))!)
cell.actionCallBack = self

let empIdNumber = NSString(string: (directoryPresenter!.getManagementItem(position: indexPath.row).agmid))


if let cachedImage = self.cache.object(forKey: empIdNumber) {
cell.profileImage.kf.base.image = cachedImage
} else {
directoryPresenter?.getProfileImage(id: empIdNumber as String) { image in
cell.profileImage.kf.base.image = image
self.cache.setObject(image!, forKey: empIdNumber)
}
}
return cell
}
}

自定义单元格内的数据绑定

在重新使用之前,我将图像数据设为零

override func prepareForReuse() {
profileImage.kf.base.image = nil
}

并在onBind((数据方法中设置相应的数据。

func onBindCell(management: Management) {
name.text = management.getEmployeeDisplayName()

// Place Holder
profileImage.kf.base.image = UIImage(named: management.details.gender == "M" ? "placeholder_profile_male" : "placeholder_profile_female")

}

不过,当第一次向下滚动视图时,图像会闪烁。加载准确的图像后,它不会闪烁。如何在第一次滚动时对初始闪烁问题进行排序?

如果仍然使用KingFisher,但告诉它如何解释/处理下载的数据呢?

让我们创建自己的ImageProcessor:

struct CustomBase64Processor: ImageProcessor {
var identifier: String = "com.larme.customBase64Processor"
var encoding: String.Encoding = .utf8
func process(item: ImageProcessItem, options: KingfisherParsedOptionsInfo) -> KFCrossPlatformImage? {
print("CustomBase64Processor Processing: (item)")
switch item {
case .image(let image):
return image
case .data(let data):
// Strip the Base 64 data
if let utf8String = String(data: data, encoding: encoding) {
//Remove Data URI if needed
let base64String = utf8String.replacingOccurrences(of: "data:image\/.*?;base64,",
with: "",
options: .regularExpression)
// Convert into a Data the Base64 Encoded String
if let cleanedData = Data(base64Encoded: base64String.trimmingCharacters(in: .whitespacesAndNewlines)) {
return KFCrossPlatformImage(data: cleanedData)
} else {
// Just an attempt here, but in fact it could be a gif, and that's not supported.
// Let's rely on KFCrossPlatformImage initilization
return KFCrossPlatformImage(data: Data(base64String.utf8))
}
} else {
//Default image data aren't UTF8 Convertible, and are "ready to process"
return KFCrossPlatformImage(data: data)
}
}
}
}

我想知道你是否有数据URI(因为它让我想到了相关的问题(,即内容是data:image/png;base64,theBase64Data,所以如果需要,我添加了一个删除它的内容。

在使用中,它是这样的:

imageView.kf.setImage(with: url,
placeholder: nil,
options: [.processor(CustomBase64Processor())]) { result in
print("KingFisher callback: (result)")
switch result {
case .success(let imageresult):
print("Success: (imageresult)")
case .failure(let error):
print("Error: (error)")
}
}

小心,既然我做了一个处理器,我们应该得到一个data来解释。因此,如果您想使用其他处理(如调整大小等(,请先处理基底64,以获得真实的工作图像。

它还没有经过充分的测试,但我想这可能是一个良好的开端。

我认为应该使用库从url 加载图像

最新更新