[英]Images in UITableView keep re-loading and wrong images flash while scrolling
[英]Images in UITableView keep re-loading and wrong images flash while scrolling in swift
该应用程序有一个 UITable View,可将动态图像加载到单元格中。 滚动时下载图像,并将它们转换为 UIImage。 这些 UIImages 将在 KingFisher 的帮助下设置为 ImageView。 简单的缓存机制已经实现,但图像是 flash 滚动,直到准确的图像加载。 代码在下面提到。
表视图代码
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
时,您不应管理图像的下载/缓存,因为这是该库的责任
所以更换
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)
}
}
和
let url = URL(string: directoryPresenter!.getManagementItem(position: indexPath.row).agmid)
cell.profileImage.kf.setImage(with: url,placeholder: UIImage(named: "placeholderImage"))
仍然使用 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)
}
}
}
}
我想知道您是否有 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
来解释。 因此,如果您想使用其他处理(如调整大小等),请先处理 base 64,然后才能获得真正的工作图像。
它尚未经过全面测试,但我想这可能是一个好的开始。
我认为您应该使用库从 url 加载图像
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.