RootViewController - tableView:cellForRowAtIndexPath - 从assetsLibrary加载图像

时间:2011-09-29 16:52:35

标签: iphone ios image objective-c-blocks alasset

StackOverflow的朋友和同事程序员,

我的RootViewController(视图上的flowerTableView)应该显示包含标题,副标题和图像缩略图(从相机胶卷加载)的单元格。我猜是一个非常基本的表。

所有内容都存储在“核心数据”中。但是图像作为imagePaths存储到相机胶卷。示例:flower.imagePath = assets-library://asset/asset.JPG?id=1000000002&ext

使用底部的代码,一切都应该顺利进行,但事实并非如此。启动应用程序时,会显示标题和副标题,但图像不是。当我按下显示详细视图的单元格,然后再次弹回到主视图时,将显示该特定单元格的图像。

当我按下“全部显示”时,工具栏上的按钮会执行以下代码

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];

并重新加载表格,现在展示了所有美丽的花朵。

为什么第一次没有展示花?这是一个缓存问题吗?

调试此代码时,字符串:'此函数完成后记录此调试字符串'在启动应用程序时加载表格后记录,而不是在按下显示全部' 这意味着所有图像都是从相机胶卷成功加载的,但在显示单元后附加到单元格,因此不显示。

按“显示全部”

时,按照预期打印相同的行

希望有人可以告诉我这里发生了什么,甚至更好,我的代码中有什么要改变才能使其发挥作用。我现在卡住了......

感谢帮帮我! 埃德

::: 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;
}

2 个答案:

答案 0 :(得分:2)

- [ALAssetsLibrary assetForURL: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];
}

答案 1 :(得分:-1)

研究员Overflowist让我提出以下解决方案:

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

中创建单元格

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

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