web-dev-qa-db-fra.com

cellule imageView dans UITableView n'apparaît pas tant que cette option n'est pas sélectionnée

  1. Voici une vidéo du problème: http://youtu.be/Jid0PO2HgcU

  2. J'ai un problème lorsque j'essaie de définir l'image pour la [cellule imageView] dans un UITableView à partir de la bibliothèque d'actifs.

L'image est chargée mais elle n'apparaît pas dans la cellule tant que je n'ai pas touché (sélectionné) cette cellule. Voici mon code qui définit l'imageView de la cellule:

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

Le code ci-dessus fait partie de la:

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

Des idées?

28
Ali

Je pense que dans ce cas, vous utilisez une UITableViewCell définie par iOS (et non une personnalisée), qui est l'une de ces cellules que vous obtenez de "initWithStyle: reuseIdentifier:". Désormais, ces cellules sont construites en interne de telle sorte que si vous n'affectez pas un contenu immédiatement, la sous-vue correspondante ne sera pas ajoutée dans la hiérarchie contentView de la cellule. Ce type de comportement est typique des vues personnalisées complexes, où la disposition finale des cellules ne peut être déterminée que lorsque le contenu de toutes ses sous-vues est complètement spécifié. (Par exemple, vous avez deux libellés, disons les libellés A et B, le libellé A est multiroues et vous souhaitez ajouter le libellé B immédiatement sous le libellé A, vous ne pouvez alors placer correctement le libellé B qu’une fois que vous aurez le contenu du libellé-A. et vous calculez sa hauteur.). Donc, je suppose que les cellules de table iOS intégrées sont réalisées de la même manière et que la hiérarchie des sous-vues est construite au stade "layoutSubviews". 

Dans votre cas, vous créez la cellule mais ajustez l'heure à laquelle l'image est fournie. Mais à ce stade, layoutSubviews a encore été appelé et sans image, l'imageView correspondante n'est même pas allouée et ajoutée dans la hiérarchie contentView!

Donc, selon moi, la solution pour vous est juste d'attribuer immédiatement un "espace réservé" pour votre actif (l'espace réservé peut être une image transparente bien sûr) qui vous garantira la création interne de UIImageView. Faites attention à la taille de l'image, elle devrait être proche de la taille de l'image attendue, pour la même raison que celle expliquée ci-dessus. Dès que votre bloc d'arrivée s'appelle, la vue de l'image devrait déjà être là et l'image va apparaître.

La raison pour laquelle, lorsque vous appuyez sur la cellule, l’image apparaît, est due au fait que cette opération appelle à nouveau le layoutSubviews. Dans ce cas, tout le code est probablement ré-exécuté et comme vous l'avez déjà appelé "setImage:", la propriété interne "image" est alors définie et la hiérarchie contentView sera reconstruite avec la nouvelle image.

Une autre solution possible à votre problème consiste bien entendu à utiliser un UITableViewCell "personnalisé" (chargé par exemple à partir d'un Nib). Dans ce cas, toutes vos sous-vues seront chargées et vous accéderez simplement à UIImageView à l’aide de sa balise (lisez la documentation Apple pour en savoir plus sur cette technique utile pour créer des cellules de vue tableau à partir d’un fichier Nib).

40
viggio24

vous devez disposer la cellule après la définition de l'image

juste comme

[cell setNeedsLayout];

26
ibcker

Je me suis gratté la tête pendant si longtemps et j'ai finalement compris. 

Mon erreur est que je plaçais l'image dans cell.imageView alors que je devrais régler mon cell.eventImageView actuel. Il s'agissait de la vue d'image générique fournie dans UITableViewCell. J'espère que ça aide quelqu'un.

6
atulkhatri

Voici comment j'ai résolu ce problème, je sais que ce n'est pas le meilleur mais que ça marche :)

    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;
    });
1
Jan Timar

Dans mon cas, je configurais une cellule prototype via un Storyboard, mais j'utilisais accidentellement la méthode dequeueCellWithIdentifier:forIndexPath au lieu de dequeueCellWithIdentifier:

La première méthode ne doit être utilisée que lors de l’appropriation de cellules à une table par l’intermédiaire des méthodes programmables UITableView registerClass:forReuseIdentifier: ou registerNib:forReuseIdentifier

1
Yerk

J'avais un problème similaire. J'avais enregistré la classe UITableViewCell par défaut au lieu de ma classe personnalisée.

J'ai eu ceci:

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

mais j'aurais dû avoir ceci:

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

La création de la cellule semblait fonctionner au fur et à mesure que je passais dans le débogueur, mais rien ne se présentait jusqu'à ce que je sélectionne chaque ligne. 

0
HalR

Parfois, cela se produit lorsque vous utilisez la variable UITableViewCell personnalisée avec des étiquettes, des images, etc., mais aussi quelque part que vous définissez la valeur UILabel par défaut de la cellule. par exemple

customCell.textLabel.text = @"some text"

Pour résoudre ce problème, évitez d'utiliser l'étiquette par défaut, mais ajoutez votre propre UILabel dans votre cellule personnalisée.

0
MrWaqasAhmed

J'ai le même problème quand j'utilise ce code:

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!";
        }

Mais je le répare en remplaçant: 

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

À:

cell = [cell initWithStyle:UITableViewCellStyleDefault reuseIdentifier:kCellSection1];
0
Tà Truhoada