RootViewController - tableView: cellForRowAtIndexPath - загрузить изображение из assetsLibrary - PullRequest
0 голосов
/ 29 сентября 2011

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

и перезагрузка таблицы, теперь отображаются все красивые цветы.

Почему цветы не отображались в первый раз?Это проблема кеширования?

При отладке этого кода строка: «Эта строка отладки была зарегистрирована после выполнения этой функции» регистрировалась после загрузки таблицы при запуске приложения, а не после нажатия «Показать все».означает, что все изображения загружаются из камеры успешно, но прикреплены к ячейке после того, как ячейка была отображена и, следовательно, не показана.

Эта же строка печатается, как и предполагалось, при нажатии «Показать все»

Надеюсь, кто-то может сказать мне, что здесь происходит и даже лучше, что нужно изменить в моем коде, чтобы эта работа работала.Я застрял на данный момент ...

Спасибо за помощь мне!Эдвин

::: КОД :::

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

2 голосов
/ 29 сентября 2011

- [ALAssetsLibrary assetForURL: resultBlock: failBlock] выполняется асинхронно. Это означает, что вызов немедленно возвращается в вашем 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];
}
0 голосов
/ 29 сентября 2011

Fellow Overflowist позвольте мне предложить следующее решение:

вместо создания ваших ячеек в - (UITableViewCell *) tableView: (UITableView *) tableView cellForRowAtIndexPath (NSIndexPath *) indexPath

создайте NSMutableArray, заполненный UITableViewCells (те же, что вы создаете в методе cellForRowAtIndexPath), который вы хотите отобразить в таблице и просто вернуть соответствующий UITableViewCell (который будет объектом в NSMutableArray) в методе cellForRowAtIndexPath.

Таким образом, метод cellForRowAtIndexPath будет показывать ячейки, которые уже были загружены и готовы к показу.

...