2012-02-19 11 views
27
  1. Oto film o problemie: http://youtu.be/Jid0PO2HgcUkomórka ImageView w UITableView nie pojawia się aż wybrany

  2. Mam problem, gdy próbuje ustawić obraz na komórki ImageView [] w UITableView z biblioteka zasobów.

Obraz jest załadowany, ale nie pojawia się w komórce, dopóki nie dotknę (zaznacz) tej komórki. Tu jest mój kod, który ustawia ImageView komórki:

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

Powyższy kod jest częścią:

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

Jakieś pomysły?

+0

wierzę, że [to] (http://blog.slaunchaman.com/2011/08/14/cocoa-touch-circumventing-uitableviewcell-redraw-issues-with-mithithreading/) artykuł dotyczy twojego problemu. Spójrz na to. –

Odpowiedz

39

Myślę, że w tym przypadku używasz zdefiniowanej przez iOS metody UITableViewCell (a nie niestandardowej), która jest jedną z tych komórek, które można uzyskać z "initWithStyle: reuseIdentifier:". Teraz te komórki są zbudowane wewnętrznie w taki sposób, że jeśli nie przypiszesz bezpośrednio zawartości, odpowiedni widok nie zostanie dodany w hierarchii contentView komórki. Takie zachowanie jest typowe dla złożonych widoków niestandardowych, w których ostateczny układ komórki można określić tylko wtedy, gdy wszystkie jej subviews mają pełną treść. (Np. Masz dwie etykiety, powiedzmy etykietę A i etykietę B, etykieta A jest multirow i chcesz dodać etykietę-B bezpośrednio pod etykietą-A, wtedy możesz umieścić etykietę-B poprawnie tylko wtedy, gdy masz etykietę-A i obliczysz jego wysokość.). Przypuszczam więc, że wbudowane komórki tabeli iOS są wykonywane w ten sam sposób, a hierarchia podelektronów jest budowana na etapie "layoutSubviews".

W przypadku, gdy utworzysz komórkę, odroczysz czas dostarczenia obrazu. Ale w tym momencie wywołano layoutSubviews i bez żadnego obrazu odpowiedni imageView nie został nawet przydzielony i dodany w hierarchii contentView!

Tak więc, według mnie, rozwiązaniem dla Ciebie jest natychmiastowe przypisanie "symbolu zastępczego" dla Twojego zasobu (może to być oczywiście przezroczysty obraz), który zagwarantuje Ci wewnętrzne tworzenie UIImageView. Należy zachować ostrożność przy rozmiarze obrazu, który powinien być zbliżony do oczekiwanego rozmiaru obrazu, z tego samego powodu, o którym mowa powyżej. Jak tylko twój blok końcowy zostanie wywołany, widok obrazu powinien już tam być i pojawi się obraz.

Powodem, dla którego po dotknięciu komórki obraz wyświetlany jest fakt, że operacja ta ponownie wywołuje layoutSubviews. W tym przypadku cały kod prawdopodobnie zostanie ponownie wykonany i jak już wcześniej nazywano "setImage:", wówczas ustawiana jest wewnętrzna właściwość "image", a hierarchia contentView zostanie odbudowana z nowym obrazem.

Innym możliwym rozwiązaniem problemu jest użycie "niestandardowego" UITableViewCell (np. Załadowanego ze stalówki). W takim przypadku wszystkie Twoje subviews zostaną załadowane, a Ty po prostu uzyskasz dostęp do UIImageView za pomocą jego tagu (przeczytaj pliki apple docs, aby dowiedzieć się więcej na temat tej przydatnej techniki tworzenia komórek widoku tabeli z pliku Nib).

+0

Dziękuję. Bardzo informujące. – Ali

+1

Zrobiłem rozwiązanie zastępcze i działa jak magic.I utknąłem na chwilę. Oto kod zaraz po instrukcji if: 'UIImage * placeholderImage = [UIImage imageNamed: @" placeholder.png "]; [[obraz komórki] setImage: [obraz zastępczy obrazuByScalingAndCroppingForSize: CGSizeMake (36.0, 42.0)]]; ' – Ali

+2

Viggio ma poprawną ocenę problemu, jednak znacznie prostszym rozwiązaniem jest wywołanie metody' layoutSubviews' komórkę natychmiast po przypisaniu obrazu do widoku obrazu komórki. Spowoduje to, że komórka ponownie przejdzie przez proces układania. Ponieważ obraz jest obecny tym razem, pojawi się! – mklbtz

1

To moja droga, jak i rozwiązać te problemy, wiem, że nie jest najlepszy, ale że praca :)

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

Dzięki! to działało idealnie –

+5

Proszę, nie rób tego! –

6

Podrapałem głowę tak długo i wreszcie zdobione.

Mój błąd polegał na tym, że ustawiam obraz w cell.imageView, kiedy powinienem ustawić mój aktualny numer cell.eventImageView.Pomyślał o ogólnym widoku obrazu podanym w UITableViewCell. Mam nadzieję, że to pomaga komuś.

25

trzeba układ komórkę po obrazu ustawiony

jak

[komórka setNeedsLayout];

+0

Dzięki, rozwiązał problem –

+0

dziękuję! rozwiązał również mój problem. – shadowmoses

1

W moim przypadku było stworzenie prototypu ogniwa poprzez storyboard, ale został przypadkowo stosując metodę dequeueCellWithIdentifier:forIndexPath zamiast dequeueCellWithIdentifier:.

Pierwsza metoda jest używana tylko podczas przypisywania komórek do widoku tabeli za pomocą metod programowych UITableView registerClass:forReuseIdentifier: lub registerNib:forReuseIdentifier.

0

Miałem podobny problem. Zarejestrowałem domyślną klasę UITableViewCell zamiast mojej niestandardowej klasy.

miałem to:

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

ale powinno to miał:

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

Stworzenie komórka wszystko wyglądało pracować jak ja przeszedł przez debugger, ale nic nie pokazał się, dopóki nie wybrał każdy rząd.

0

Czasami dzieje się, gdy używasz niestandardowego UITableViewCell z etykietami, obrazami itp., Ale także gdzieś ustawiasz domyślny UILabel komórki. na przykład:

customCell.textLabel.text = @"some text" 

Aby rozwiązać ten problem, należy unikać używania etykiety domyślnej, zamiast tego należy dodać własną etykietę UILabel do niestandardowej komórki.

0

mam ten sam problem, kiedy używam tego kodu:

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

Ale ja go naprawić przez wymienić:

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

Do:

cell = [cell initWithStyle:UITableViewCellStyleDefault reuseIdentifier:kCellSection1]; 
Powiązane problemy