0

StackOverflow friends and colleague programmers,

My RootViewController (a flowerTableView on a view) should display cell's with title, subtitle and an image thumbnail (loaded from the camera roll). A very basic table I guess.

All content is stored in 'Core Data' but the images are stored as imagePaths to the camera roll. Example: flower.imagePath = assets-library://asset/asset.JPG?id=1000000002&ext

Using the code at the bottom everything should run smoothly but it doesn't . When starting the App the title's and subtitle's are shown, but the images are not. When I press a cell, which display's the detail view, and pop back again to the main view the image for this specific cell is shown.

When I press 'Show All', a button on a toolbar which executes the following code

NSFetchRequest *fetchRequest = [[self fetchedResultsController] fetchRequest];
[fetchRequest setPredicate:nil];

NSError *error = nil;
if (![[self fetchedResultsController] performFetch:&error]) {
    NSLog(@"Unresolved error %@, %@", error, [error userInfo]);
    abort();
}
[self.flowerTableView reloadData];

and reloads the table, all the beautiful flowers are now shown.

Why didn't the flowers be displayed the first time? Is this a caching problem?

When debugging this code the string: 'This debug string was logged after this function was done' was logged after loading the table on starting the app, not after pressing 'Show All' This means that all images are loaded from the camera roll successfully but attached to the cell after the cell was displayed and therefore not shown.

The same line is printed as intended when pressing 'Show All'

Hope someone can tell me what's going on here and even better, what to change in my code to make this work. I'm stuck at the moment...

Thank for helping me out! Edwin

:::THE CODE:::

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

    Flower *flower = [fetchedResultsController_ objectAtIndexPath:indexPath];

    static NSString *CellIdentifier = @"Cell";

    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
    if (cell == nil) {
        cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:CellIdentifier] autorelease];
    }

    // Configure the cell...

    // Display the image if one is defined
    if (flower.imagePath && ![flower.imagePath isEqualToString:@""])
    {
        // Should hold image after executing the resultBlock
       __block UIImage *image = nil;

        ALAssetsLibraryAssetForURLResultBlock resultBlock = ^(ALAsset *asset)
        {
            NSLog(@"This debug string was logged after this function was done");
            image = [[UIImage imageWithCGImage:[asset thumbnail]] retain];
        };

        ALAssetsLibraryAccessFailureBlock failureBlock  = ^(NSError *error)
        {
            NSLog(@"Unresolved error: %@, %@", error, [error localizedDescription]);
        };

        [assetsLibrary_ assetForURL:[NSURL URLWithString:flower.imagePath] 
                        resultBlock:resultBlock
                       failureBlock:failureBlock];

        [cell.imageView setImage:image];
    }

    return cell;
}
4

2 回答 2

2

-[ALAssetsLibraryassetForURL:resultBlock:failureBlock] 异步运行。这意味着调用会立即在您的 tableView:cellForRowAtIndexPath: 方法中返回。在实际加载资产之前,单元格会显示在表格视图中。

您需要做的是为结果块中的单元格设置图像。像这样的东西:

if (flower.imagePath && ![flower.imagePath isEqualToString:@""])
{
    ALAssetsLibraryAssetForURLResultBlock resultBlock = ^(ALAsset *asset)
    {
        NSLog(@"This debug string was logged after this function was done");
        [cell.imageView setImage:[UIImage imageWithCGImage:[asset thumbnail]]];

        //this line is needed to display the image when it is loaded asynchronously, otherwise image will not be shown as stated in comments
        [cell setNeedsLayout]; 

    };

    ALAssetsLibraryAccessFailureBlock failureBlock  = ^(NSError *error)
    {
        NSLog(@"Unresolved error: %@, %@", error, [error localizedDescription]);
    };

    [assetsLibrary_ assetForURL:[NSURL URLWithString:flower.imagePath] 
                    resultBlock:resultBlock
                   failureBlock:failureBlock];
}
于 2011-09-29T18:08:11.430 回答
-1

溢出主义者让我提出以下解决方案:

而不是在 - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath (NSIndexPath *)indexPath

创建一个 NSMutableArray,其中填充了要在表中显示的 UITableViewCells(与您在 cellForRowAtIndexPath 方法中创建的相同),并在 cellForRowAtIndexPath 方法中简单地返回相关的 UITableViewCell(它将是 NSMutableArray 中的一个对象)。

这样,cellForRowAtIndexPath 方法将显示已经加载并准备好显示的单元格。

于 2011-09-29T19:11:32.403 回答