2012-02-19 6 views
27
  1. Ecco un video del problema: http://youtu.be/Jid0PO2HgcUImageView cellula UITableView non appare fino selezionata

  2. Ho un problema quando si cerca di impostare l'immagine per il [IMAGEVIEW cellulare] in un UITableView da la biblioteca delle risorse.

L'immagine viene caricata ma non appare nella cella finché non tocco (seleziona) quella cella. Ecco il mio codice che imposta l'ImageView della cella:

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

Il codice di cui sopra è parte del:

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

Tutte le idee?

+0

Credo che [questo] (http://blog.slaunchaman.com/2011/08/14/cocoa-touch-circumventing-uitableviewcell-redraw-issues-with-multithreading/) l'articolo è pertinente al tuo problema. Date un'occhiata a questo. –

risposta

39

Penso che in questo caso si utilizzi un UITableViewCell definito da iOS (e non uno personalizzato), ovvero una di quelle celle che si ottiene da "initWithStyle: reuseIdentifier:". Ora queste celle sono costruite internamente in modo tale che se non si assegna alcun contenuto immediatamente, la sottoview corrispondente non verrà aggiunta nella gerarchia contentView della cella. Questo tipo di comportamento è tipico delle visualizzazioni personalizzate complesse, in cui il layout finale della cella può essere determinato solo quando tutte le sue sottoview hanno il loro contenuto completamente specificato. (Ad esempio hai due etichette, diciamo l'etichetta A e l'etichetta B, l'etichetta A è multipla e vuoi aggiungere l'etichetta-B immediatamente sotto l'etichetta-A, quindi puoi posizionare l'etichetta-B correttamente solo quando hai il contenuto dell'etichetta-A e tu calcoli la sua altezza.). Quindi suppongo che le celle della tabella iOS integrate siano fatte nello stesso modo e la gerarchia delle subviews sia costruita nella fase "layoutSubviews".

Nel tuo caso si crea la cella ma si differisce il tempo in cui viene fornita l'immagine. Ma a questo punto è stato chiamato il layoutSubviews e senza alcuna immagine il corrispondente imageView non è nemmeno assegnato e aggiunto nella gerarchia contentView!

Quindi, secondo me, la soluzione per te è solo quella di assegnare immediatamente un "segnaposto" per il tuo bene (il segnaposto può essere un'immagine trasparente ovviamente) che ti garantirà la creazione interna di UIImageView. Prestare attenzione alle dimensioni dell'immagine, dovrebbe essere vicino alla dimensione dell'immagine prevista, per la stessa ragione spiegata sopra. Non appena viene chiamato il tuo blocco finale, la vista dell'immagine dovrebbe essere già lì e l'immagine apparirà.

Il motivo per cui quando si tocca la cella viene visualizzata l'immagine, è dovuto al fatto che questa operazione chiama di nuovo il layout di anteprima. In questo caso l'intero codice viene probabilmente rieseguito e, come hai già chiamato "setImage:", prima viene impostata la proprietà interna "immagine" e la gerarchia contentView verrà ricostruita con la nuova immagine.

Un'altra possibile soluzione al problema è ovviamente utilizzare un UITableViewCell "personalizzato" (ad esempio caricato da un pennino). In tal caso verranno caricate tutte le sottoview e sarà sufficiente accedere a UIImageView usando il suo tag (leggi i documenti Apple per saperne di più su questa tecnica utile per creare celle di visualizzazione tabella da un file Nib).

+0

Grazie. Molto informativo. – Ali

+1

Ho fatto la soluzione di segnaposto e funziona come per magia. Sono rimasto bloccato per un po '. Ecco il codice subito dopo l'istruzione if: 'UIImage * placeholderImage = [UIImage imageNamed: @" placeholder.png "]; [[cell imageView] setImage: [placeholderImage imageByScalingAndCroppingForSize: CGSizeMake (36.0, 42.0)]]; ' – Ali

+2

Viggio ha ragione nella sua valutazione del problema, tuttavia una soluzione molto più semplice è chiamare il metodo' layoutSubviews' sul tuo cella subito dopo aver assegnato l'immagine alla vista dell'immagine della cella. Ciò farà sì che la cella riprenda il processo di layout. Poiché l'immagine è presente questa volta, apparirà! – mklbtz

1

Questo è il mio modo come ho risolto questi problemi, so che non è la migliore, ma che il lavoro :)

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

Grazie! quello ha funzionato perfettamente –

+5

Per favore, non farlo! –

6

Ho graffiato la mia testa per tanto tempo e finalmente capito.

L'errore era che stavo impostando l'immagine in cell.imageView quando dovrei impostare la mia presa effettiva cell.eventImageView.Stava scherzando con la generica imageview fornita in UITableViewCell. Spero che aiuti qualcuno.

25

è necessario per il layout delle cellule dopo immagine impostata

proprio come

[cella setNeedsLayout];

+0

Grazie, è stato risolto il problema –

+0

grazie! risolto anche il mio problema. – shadowmoses

1

Nel mio caso mi è stato la creazione di un prototipo di cella attraverso uno storyboard, ma è stato accidentalmente utilizzando il metodo dequeueCellWithIdentifier:forIndexPath invece di dequeueCellWithIdentifier:.

Il primo metodo deve essere utilizzato solo quando si appropriano le celle a una vista tabella tramite i metodi UITableView registerClass:forReuseIdentifier: o registerNib:forReuseIdentifier programmatico.

0

Stavo avendo un problema simile. Avevo registrato la classe UITableViewCell predefinita invece della mia classe personalizzata.

ho avuto questo:

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

ma avrei avuto questo:

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

La creazione delle cellule tutto sembrava di essere al lavoro come ho fatto un passo attraverso il debugger, ma nulla ha mostrato fino a quando ho selezionato ogni riga

0

A volte capita quando si utilizza UITableViewCell personalizzato con etichette, immagini ecc. Ma anche da qualche parte si imposta la UILabel di cella predefinita. per esempio

customCell.textLabel.text = @"some text" 

Per risolvere questo problema, evitare di utilizzare l'etichetta di default, invece aggiungere la tua UILabel nella tua cella personalizzato.

0

ottengo stesso problema quando uso questo codice:

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

Ma io risolvere il problema da sostituire:

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

A:

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