2012-02-19 13 views
27
  1. Aquí hay un video del problema: http://youtu.be/Jid0PO2HgcUimageView celular en UITableView no aparece hasta que se seleccionen

  2. tengo un problema cuando se trata de establecer la imagen de la [imageView celular] en un UITableView de la biblioteca de activos.

La imagen está cargada pero no aparece en la celda hasta que toco (seleccione) esa celda. Aquí está mi código que establece la imageView de la célula:

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

El código anterior es parte de la:

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

¿Alguna idea?

+0

Creo que [esto] (http://blog.slaunchaman.com/2011/08/14/cocoa-touch-circumventing-uitableviewcell-redraw-issues-with-multithreading/) el artículo es relevante para su problema. Échale un vistazo. –

Respuesta

39

Creo que en este caso estás usando una UITableViewCell definida por iOS (y no una personalizada), que es una de esas celdas que obtienes de "initWithStyle: reuseIdentifier:". Ahora estas celdas están construidas internamente de tal forma que si no asigna algún contenido inmediatamente, la subvista correspondiente no se agregará a la jerarquía contentView de la celda. Este tipo de comportamiento es típico de vistas personalizadas complejas, donde el diseño final de la celda se puede determinar solo cuando todas sus subvistas tengan su contenido completamente especificado. (Por ejemplo, tiene dos etiquetas, digamos etiqueta A y etiqueta B, etiqueta A es multirruta y desea agregar la etiqueta B inmediatamente debajo de la etiqueta A, luego puede colocar la etiqueta B correctamente solo una vez que tenga la etiqueta: contenido A y calcula su altura). Entonces, supongo que las celdas integradas de la tabla iOS se hacen de la misma manera y la jerarquía de subvistas se construye en la etapa "layoutSubviews".

En su caso, cree la celda pero difiera el tiempo de entrega de la imagen. ¡Pero en este momento el layoutSubviews ha sido llamado todavía y sin ninguna imagen el imageView correspondiente ni siquiera se asigna y se agrega en la jerarquía de contentView!

Así que, según yo, la solución para usted es simplemente asignar inmediatamente un "marcador de posición" para su activo (el marcador de posición puede ser una imagen transparente del curso) que le garantizará la creación interna de UIImageView. Tenga cuidado con el tamaño de la imagen, debe estar cerca del tamaño de imagen esperado, por la misma razón explicada anteriormente. Tan pronto como se llame al bloque de acabado, la vista de la imagen ya debe estar allí y aparecerá la imagen.

El motivo por el que al tocar sobre la celda aparece la imagen, se debe a que esta operación vuelve a llamar a layoutSubviews. En este caso, probablemente todo el código se vuelva a ejecutar y, como ya lo llamó "setImage:", entonces se establece la propiedad de "imagen" interna y la jerarquía de contentView se reconstruirá con la nueva imagen.

Otra posible solución a su problema es, por supuesto, utilizar una UITableViewCell "personalizada" (por ejemplo, cargada desde un Nib). En tal caso, todas sus subvistas se cargarán y usted simplemente tendrá acceso a UIImageView usando su etiqueta (lea los documentos de Apple para conocer más acerca de esta útil técnica para crear celdas de vista de tabla a partir de un archivo Nib).

+0

Gracias. Muy informativo. – Ali

+1

Hice la solución de marcador de posición y funciona como magia. Estuve atascado por un tiempo. Aquí está el código justo después de la instrucción if: 'UIImage * placeholderImage = [UIImage imageNamed: @" placeholder.png "]; [[image imageView] setImage: [placeholderImage imageByScalingAndCroppingForSize: CGSizeMake (36.0, 42.0)]]; ' – Ali

+2

Viggio tiene razón en su evaluación del problema; sin embargo, una solución mucho más simple es llamar al método' layoutSubviews' en su celda inmediatamente después de asignar su imagen a la vista de imagen de la celda. Esto hará que la celda vuelva a pasar por el proceso de diseño. ¡Ya que la imagen está presente esta vez, aparecerá! – mklbtz

1

Este es mi camino que he resuelto estos problemas, sé que no es el mejor, pero que el trabajo :)

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; 
    }); 
+0

¡Gracias! que funcionó perfectamente –

+5

¡Por favor, no lo hagas! –

6

Me rasqué la cabeza durante tanto tiempo y finalmente lo descubrió.

Mi error fue que estaba configurando la imagen en cell.imageView cuando debería configurar mi salida real cell.eventImageView.Estaba jugando con la vista de imagen genérica proporcionada en UITableViewCell. Espero que ayude a alguien.

25

que necesita a la disposición celular después de imagen establecida

igual

[celular setNeedsLayout];

+0

Gracias, se resolvió el problema –

+0

gracias! Resolvió mi problema también. – shadowmoses

1

En mi caso fue la creación de una célula a través de un prototipo de Storyboard, pero fue accidentalmente utilizando el método dequeueCellWithIdentifier:forIndexPath en lugar de dequeueCellWithIdentifier:.

El primer método solo debe utilizarse al asignar celdas a una vista de tabla mediante los métodos programáticos UITableView registerClass:forReuseIdentifier: o registerNib:forReuseIdentifier.

0

Estaba teniendo un problema similar. Había registrado la clase UITableViewCell predeterminada en lugar de mi clase personalizada.

Tenía esta:

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

pero debería haber tenido esto:

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

La creación de células todo parecía estar funcionando como entré a través del depurador, pero nada apareció hasta que seleccionado cada fila

0

En algún momento ocurre cuando está usando UITableViewCell personalizado con etiquetas, imágenes, etc. pero también en algún lugar está configurando UILabel de celda por defecto. por ejemplo

customCell.textLabel.text = @"some text" 

Para resolver este problema, evite el uso de identificación por defecto, en lugar añadir su UILabel en su celda personalizado.

0

me sale mismo problema cuando se utiliza este código:

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

Pero lo fijan por reemplazar:

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

Para:

cell = [cell initWithStyle:UITableViewCellStyleDefault reuseIdentifier:kCellSection1]; 
Cuestiones relacionadas