簡體   English   中英

tableview中的單元格滾動不流暢

[英]cells in tableview not scrolling smoothly

我已經完成了我的應用程序的編碼,但是仍然有一個問題,我無法解決數周的問題……我在該站點和其他網站上瀏覽了相同的問題,但是找不到解決方法。 我有一個表格單元格視圖(如Instagram),其中包含從服務器下載的圖像。 我的問題是,當我滾動表格視圖時,它不平滑且閃爍。

要構造表視圖,請執行以下操作:

-標題視圖和單元格是子類的。 -我異步下載所有圖像,然后將其緩存(每個圖像約25Ko)在我的應用程序的tmp文件夾中。 -下載的每個圖像與應放置圖像的UIImageView具有相同的框架。 -我嘗試將圖像保存為png和jpeg格式,但問題仍然存在。

我進行了另一個測試,而不是將下載的圖像放入單元格中,而是將圖像放入應用程序中(可以任意縮放)。 在這種情況下,表格視圖會平滑滾動。

因此,我懷疑問題可能出在我緩存圖像並從緩存中獲取圖像的方式上。 但是即使在這種情況下,我也嘗試使用NSCache和一個臨時文件夾來緩存圖像,但是沒有結果...

這是我的代碼:

-(void)CacheTheImageDownloaded: (NSData *)TheImageData : (NSString*)PathOfImage{

   NSFileHandle *fout;
   [[NSFileManager defaultManager] createFileAtPath:PathOfImage contents:Nil   attributes:Nil];
   fout = [NSFileHandle fileHandleForWritingAtPath:PathOfImage];
   [fout writeData:TheImageData ];
   [fout closeFile];

}


-(UIImage*)GetTheImageFromTemporaryDirectory:(NSString*)ImagePath{
   UIImage *theCachedImage;
   theCachedImage = [UIImage imageWithContentsOfFile:ImagePath];
   return theCachedImage;
}


-(void)GetImageForTheViewedCell: (NSString*) ImageName : (NSString*)TheImageURL :    (NSInteger)therow : (UIImageView*)MyImageView {

  NSString *TheKey = [NSString stringWithFormat:@"%ld", (long)therow];
  NSString *tmpDir = NSTemporaryDirectory();
  NSString *ImageDownloadedTmpDir;
  ImageDownloadedTmpDir = [tmpDir stringByAppendingPathComponent:@"TMPImagesDownloaded"];

  NSMutableString *TheImagePath = [NSMutableString stringWithString:ImageDownloadedTmpDir];
  [TheImagePath appendString:@"/"];
  [TheImagePath appendString:ImageName ];

if ( [self VerifyIfImageIsAlreadyCached:TheImagePath]){
    MyImageView.image = [self GetTheImageFromTemporaryDirectory:TheImagePath];
}
else{
    NSBlockOperation *loadImageIntoCellOp = [[NSBlockOperation alloc] init];
    [loadImageIntoCellOp addExecutionBlock:^(void){
        dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0),  ^{
            NSURL *theURL = [NSURL URLWithString:TheImageURL];
            NSData *data1 = [NSData dataWithContentsOfURL:theURL ];
            NSData *data = UIImagePNGRepresentation([UIImage imageWithData:data1]);
            dispatch_sync(dispatch_get_main_queue(), ^{
                MyImageView.image = [UIImage imageWithData:data];
                NSBlockOperation *ongoingDownloadOperation =       [self.TheImageDownloadOperations objectForKey:TheKey];
                if (ongoingDownloadOperation) {
                    [self.TheImageDownloadOperations removeObjectForKey:TheKey];
                }
                [self CacheTheImageDownloaded:data :TheImagePath];
            });
        });
    }];

    if (TheKey) {
        [self.TheImageDownloadOperations setObject:loadImageIntoCellOp forKey:TheKey];
    }

    if (loadImageIntoCellOp) {
        [self.imageLoadingOperationQueue addOperation:loadImageIntoCellOp];
    }

}


}

我正在使用Xcode 5.02。

感謝您的建議!

編輯

這是我的CellForRowAtIndexpath的代碼:

-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {


 static NSString *cellIdentifier = @"myCustomCell";
 MyCell *cell = [tableView dequeueReusableCellWithIdentifier:cellIdentifier];
 if (cell == nil){
     cell = [[MyCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:cellIdentifier];
 }
[cell.contentView.subviews makeObjectsPerformSelector:@selector(removeFromSuperview)];

NSInteger row = indexPath.row;
cell.tag = row ;

//The Profile picture
NSString *theurl = self.myProfilePics[row];
NSString *TheImageName = self.TheImageNames[row];
[self GetImageForTheViewedCell:TheImageName:theurl:row: cell.ProfilePicView];  //getting image from the cache or downloaded async
[cell.TheProfilePicButton setBackgroundImage:cell.ProfilePicView.image forState:UIControlStateNormal];
[cell.contentView addSubview: cell.TheProfilePicButton];

//Username:
NSString *myusername = self.Usernames[row];
[cell.UsernameButton setTitle: myusername forState:UIControlStateNormal];
[cell.contentView addSubview:cell.UsernameButton];

//date
NSString *mydate =  self.Dates[row];
[cell.DateLabel setText: mydate];
[cell.contentView addSubview: cell.DateLabel];

return cell;

}

您說過“我試圖將圖像保存為png和jpeg格式”。 我想,您只是“保存以緩存”圖像。 然后在表UIImagePNGRepresentation中使用UIImagePNGRepresentation

當您加載許多圖像時,即使實現了“延遲加載”,UITableView的性能也非常低。

所以,我的答案是您應該使用UIImageJPEGRepresentation代替UIImagePNGRepresentation

編輯

使用UIGraphicsGetImageFromCurrentImageContext怎么樣?

UIImage *image = [UIImage imageWithContentsOfFile:filePath];
CGSize imageSize = image.size;
UIGraphicsBeginImageContextWithOptions(imageSize, NO, 0);
[image drawInRect:CGRectMake(0, 0, imageSize.width, imageSize.height)];
image = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
UIImageView *imageView = [[UIImageView alloc] initWithImage:image];

還有,NSCache如何提高性能。 這是一個樣本

@inteface YourTableViewController ()
@property (nonatomic) NSCache *cache;
@end

@implemetation YourTableViewController

.
.
.

- (UITableViewCell*)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    NSString *CellIdentifier = @"Cell";
    YourCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];

    if (cell == nil)
    {
        cell = [[YourCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
        cell.yourImageView.frame = CGRectMake((self.frame.size.width - self.rowHeight)*0.5f, 0, self.rowHeight, self.rowHeight);
    }
    [cell.imageView setImage:nil];
    dispatch_queue_t globalQueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
    dispatch_queue_t mainQueue = dispatch_get_main_queue();
    dispatch_async(globalQueue, ^(){

        UIImage *image = [self.cache objectForKey:filePath];
        if (image == nil) {
            image = [UIImage imageWithContentsOfFile:filePath];
            CGSize imageSize = image.size;
            UIGraphicsBeginImageContextWithOptions(imageSize, NO, 0);
            [image drawInRect:CGRectMake(0, 0, imageSize.width, imageSize.height)];
            image = UIGraphicsGetImageFromCurrentImageContext();
            UIGraphicsEndImageContext();
            [self.cache setObject:image forKey:filePath];
        }

        dispatch_async(mainQueue, ^(){
            if ([[tableView indexPathsForVisibleRows] containsObject:indexPath]) {
                YourCell *cell = (YourCell *)[tableView cellForRowAtIndexPath:indexPath];
                if(image) {
                    [cell.yourImageView setImage:image];
                }
            }
        });
    });
    return cell;
}

.
.
.

@end

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

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