[英]UITableView with images display wrong image for a moment while scrolling
我有一個UITableView
,它有很多行,每一行只有一個圖像。 為了防止滯后,我使用了下面的代碼。 但是現在,當我滾動時,它會顯示前幾行的照片,然后進行自我修正。 如何解決這個問題?
- (void)loadImageNamed:(NSString *)name {
dispatch_async(dispatch_get_global_queue( DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^(void){
// Determine path to image depending on scale of device's screen,
// fallback to 1x if 2x is not available
NSString *pathTo1xImage = [[NSBundle mainBundle] pathForResource:name ofType:@"jpg"];
NSString *pathToImage = pathTo1xImage;
UIImage *uiImage = nil;
if (pathToImage) {
// Load the image
CGDataProviderRef imageDataProvider = CGDataProviderCreateWithFilename([pathToImage fileSystemRepresentation]);
CGImageRef image = CGImageCreateWithJPEGDataProvider(imageDataProvider, NULL, NO, kCGRenderingIntentDefault);
// Create a bitmap context from the image's specifications
// (Note: We need to specify kCGImageAlphaPremultipliedFirst | kCGBitmapByteOrder32Little
// because PNGs are optimized by Xcode this way.)
CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
CGContextRef bitmapContext = CGBitmapContextCreate(NULL, CGImageGetWidth(image), CGImageGetHeight(image), CGImageGetBitsPerComponent(image), CGImageGetWidth(image) * 4, colorSpace, kCGImageAlphaPremultipliedFirst | kCGBitmapByteOrder32Little);
// Draw the image into the bitmap context
CGContextDrawImage(bitmapContext, CGRectMake(0, 0, CGImageGetWidth(image), CGImageGetHeight(image)), image);
// Extract the decompressed image
CGImageRef decompressedImage = CGBitmapContextCreateImage(bitmapContext);
// Create a UIImage
uiImage = [[UIImage alloc] initWithCGImage:decompressedImage];
// Release everything
CGImageRelease(decompressedImage);
CGContextRelease(bitmapContext);
CGColorSpaceRelease(colorSpace);
CGImageRelease(image);
CGDataProviderRelease(imageDataProvider);
}
// Configure the UI with pre-decompressed UIImage
dispatch_async(dispatch_get_main_queue(), ^{
self.categoryImageLabel.image = uiImage;
});
});
}
其他答案告訴你該怎么做,但沒有告訴你為什么。
把一個單元格想象成你必須在醫生辦公室候診室填寫的表格。 想象一下,辦公室重復使用這些表格,每個病人在填寫他們的信息之前必須清除表格上的所有數據。
如果您沒有任何過敏症,您可能會想跳過過敏症部分,因為它們不適用於您。 但是,如果最后一個人有過敏症,並且您沒有刪除他們的答案,他們的答案仍會顯示在表格上。
同樣,當您將回收的單元出列時,您必須清除所有字段,即使是那些不適用於您的字段。 您應該將圖像設置為 nil 或它們的起始占位符值。
請注意,如果您異步加載數據,您仍應首先將字段重置為其默認值,因為舊值將顯示直到異步加載完成。 這就是你的情況。
您可以在cellForRowIndexPath
或prepareForReuse
中將圖像設置為 nil/placeholder ,但您需要在這些位置之一將其重置,否則您將看到剩余的圖像,直到新圖像完成加載。
在您的自定義單元格中寫下:
- (void)prepareForReuse {
[super prepareForReuse];
self.uiImage.image = nil;
}
你的舊圖像正在被 tableview 重用,這意味着如果 imageview 有一個圖像,當視圖回收它時它會是一樣的,所以你必須將它置零或用占位符圖像替換它,如果你有一個。
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = CustomUITableViewCell
cell.imageview.image = nil
// load your image
}
或者在您的自定義單元格調用中准備重用,每次單元格被表格重用時都會調用它:
override func prepareForReuse() {
super.prepareForReuse()
imageView.image = nil // or place holder image
}
即使接受的答案有效,但這不是推薦的方式。
根據Apple 的文檔,您應該只重置與內容無關的單元格屬性,例如 alpha、編輯和選擇狀態。
因此,處理此問題的最佳方法是在cell(for row:atIndexPath:)
設置一個默認圖像cell(for row:atIndexPath:)
以便它處理您擁有圖像的情況,如果圖像不可用則采用默認圖像,這將在您快速滾動時執行。 它尚未加載圖像,並且在單元格的重用行為中,它將選取默認圖像。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.