ячейка imageView в UITableView не отображается, пока не будет выбрана

  1. Вот видео проблемы: http://youtu.be/Jid0PO2HgcU

  2. У меня возникла проблема при попытке установить изображение для [cell imageView] в UITableView из библиотеки активов.

Изображение загружается, но не появляется в ячейке, пока я не коснусь (выберу) эту ячейку. Вот мой код, который устанавливает imageView ячейки:

//Start loading the image using the image path
NSString *path = [occasion imagePath];

if (path != nil && [path hasPrefix:@"ass"])
{
NSLog(@"photo loaded from assets library");
//testing ALAssestLibrary
ALAssetsLibrary* assetsLibrary = [[ALAssetsLibrary alloc] init];

ALAssetsLibraryAssetForURLResultBlock resultsBlock = ^(ALAsset *asset)
{
    ALAssetRepresentation *representation = [asset defaultRepresentation];
    CGImageRef imageRef = [representation fullResolutionImage]; 
    UIImage *image = [[UIImage alloc] initWithCGImage:imageRef];


    [[cell imageView] setImage:[image imageByScalingAndCroppingForSize:CGSizeMake(36.0, 42.0)]];     

    [image release];
};
ALAssetsLibraryAccessFailureBlock failureBlock = ^(NSError *error){

    NSLog(@"FAILED! due to error in domain %@ with error code %d", error.domain, error.code);
    // This sample will abort since a shipping product MUST do something besides logging a
    // message. A real app needs to inform the user appropriately.
    abort();
};        

//Convert path to an NSUrl
NSURL *url = [NSURL URLWithString:path];


// Get the asset for the asset URL to create a screen image.
[assetsLibrary assetForURL:url resultBlock:resultsBlock failureBlock:failureBlock];
// Release the assets library now that we are done with it.
[assetsLibrary release]; 
}

Приведенный выше код является частью:

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

Любые идеи?


person Ali    schedule 19.02.2012    source источник
comment
Я считаю, что это статья имеет отношение к вашей проблеме. Посмотри на это.   -  person Fernando Madruga    schedule 19.02.2012


Ответы (8)


Я думаю, что в этом случае вы используете UITableViewCell, определенный iOS (а не пользовательский), то есть одну из тех ячеек, которые вы получаете из «initWithStyle: reuseIdentifier:». Теперь эти ячейки внутренне построены таким образом, что если вы не назначите какой-либо контент немедленно, соответствующее подпредставление не будет добавлено в иерархию contentView ячейки. Такое поведение типично для сложных настраиваемых представлений, где окончательная компоновка ячеек может быть определена только тогда, когда все его подпредставления имеют полностью указанное содержимое. (Например, у вас есть две метки, скажем, метка A и метка B, метка A многострочная, и вы хотите добавить метку-B сразу под меткой-A, тогда вы сможете правильно разместить метку-B только после того, как у вас будет содержимое метки-A. и вы вычисляете его высоту.). Поэтому я предполагаю, что встроенные ячейки таблицы iOS сделаны таким же образом, а иерархия подвидов строится на этапе «layoutSubviews».

В вашем случае вы создаете ячейку, но откладываете время предоставления изображения. Но в этот момент layoutSubviews еще не был вызван, и без какого-либо изображения соответствующий imageView даже не выделяется и не добавляется в иерархию contentView!

Итак, по моему мнению, решение для вас состоит в том, чтобы сразу же назначить «заполнитель» для вашего актива (конечно, заполнитель может быть прозрачным изображением), который гарантирует вам создание внутреннего UIImageView. Будьте осторожны с размером изображения, он должен быть близок к ожидаемому размеру изображения по той же причине, что описана выше. Как только ваш финишный блок будет вызван, представление изображения должно быть уже там, и изображение появится.

Причина, по которой при нажатии на ячейку появляется изображение, связана с тем, что эта операция снова вызывает layoutSubviews. В этом случае весь код, вероятно, выполняется повторно, и, поскольку вы уже вызывали "setImage:" до этого, устанавливается внутреннее свойство "image", и иерархия contentView будет перестроена с новым изображением.

Другим возможным решением вашей проблемы, конечно же, является использование «настраиваемого» UITableViewCell (например, загруженного из Nib). В таком случае все ваши подпредставления будут загружены, и вы просто получите доступ к UIImageView, используя его тег (прочитайте документы Apple, чтобы узнать больше об этой полезной технике для создания ячеек табличного представления из файла Nib).

person viggio24    schedule 19.02.2012
comment
Я сделал заполнитель, и он работает как по волшебству. Я застрял на некоторое время. Вот код сразу после оператора if: UIImage *placeholderImage = [UIImage imageNamed:@"placeholder.png"]; [[cell imageView] setImage:[placeholderImage imageByScalingAndCroppingForSize:CGSizeMake(36.0, 42.0)]]; - person Ali; 20.02.2012
comment
Виджо прав в своей оценке проблемы, однако гораздо более простым решением является вызов метода layoutSubviews в вашей ячейке сразу после назначения вашего изображения представлению изображения ячейки. Это заставит ячейку снова пройти процесс компоновки. Поскольку на этот раз изображение присутствует, оно появится! - person mklbtz; 24.03.2015
comment
Спасибо, ты спас меня. - person Héctor; 24.06.2015

вам нужно разместить ячейку после набора изображений

как

[ячейка setNeedsLayout];

person ibcker    schedule 16.06.2015

Долго ломал голову и наконец понял.

Моя ошибка заключалась в том, что я устанавливал изображение в cell.imageView, когда я должен был установить фактическую розетку cell.eventImageView. Это было связано с общим представлением изображений, представленным в UITableViewCell. Надеюсь, это поможет кому-то.

person atulkhatri    schedule 05.12.2014

Это мой способ, как я решил эту проблему, я знаю, что это не лучший вариант, но это работает :)

    UIImage *thumbnailImage = ...

    dispatch_async(dispatch_get_main_queue(), ^{
        [cell.imageView setImage:thumbnailImage];

        UITableViewCellSelectionStyle selectionStyle = cell.selectionStyle;
        cell.selectionStyle = UITableViewCellSelectionStyleNone;
        [cell setSelected:YES];
        [cell setSelected:NO];
        cell.selectionStyle = selectionStyle;
    });
person Jan Timar    schedule 29.12.2013

В моем случае я настраивал прототип ячейки через раскадровку, но случайно использовал метод dequeueCellWithIdentifier:forIndexPath вместо dequeueCellWithIdentifier:.

Первый метод следует использовать только при присвоении ячеек табличному представлению с помощью программных методов UITableView registerClass:forReuseIdentifier: или registerNib:forReuseIdentifier.

person Yerk    schedule 25.08.2015

У меня была аналогичная проблема. Я зарегистрировал класс UITableViewCell по умолчанию вместо своего пользовательского класса.

У меня было это:

tableView.registerClass(UITableViewCell.self, forCellReuseIdentifier: visibilityCellIdentifier)

а у меня должно было быть так:

tableView.registerClass(VisibilityCell.self, forCellReuseIdentifier: visibilityCellIdentifier)

Все создание ячеек выглядело работающим, когда я проходил через отладчик, но ничего не появлялось, пока я не выбирал каждую строку.

person HalR    schedule 28.01.2016

Я получаю ту же проблему, когда использую этот код:

cell = [tableView dequeueReusableCellWithIdentifier:kCellSection1 forIndexPath:indexPath];
        if (indexPath.row == 0) {
            cell = [[UITableViewCell alloc]  initWithStyle:UITableViewCellStyleDefault reuseIdentifier:kCellSection1];
            cell.textLabel.text = @"Vote Up for me if it help for you!";
        }

Но я исправляю это, заменяя:

cell = [[UITableViewCell alloc]  initWithStyle:UITableViewCellStyleDefault reuseIdentifier:kCellSection1];

To:

cell = [cell initWithStyle:UITableViewCellStyleDefault reuseIdentifier:kCellSection1];
person Tà Truhoada    schedule 05.07.2016

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

customCell.textLabel.text = @"some text"

Чтобы решить эту проблему, избегайте использования метки по умолчанию, вместо этого добавьте свою собственную UILabel в пользовательскую ячейку.

person MrWaqasAhmed    schedule 30.03.2016