簡體   English   中英

帶有圖像的 UITableView 在滾動時顯示錯誤的圖像

[英]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 或它們的起始占位符值。

請注意,如果您異步加載數據,您仍應首先將字段重置為其默認值,因為舊值將顯示直到異步加載完成。 這就是你的情況。

您可以在cellForRowIndexPathprepareForReuse中將圖像設置為 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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM