2012-11-05 17 views
18

W każdym razie włamać się do UICollectionView, aby wywołać metodę delegowania WillDisplayCell podczas wyświetlania komórki?UICollectionView willDisplayCell delegate method?

Potrzebuję tego do leniwego ładowania i robię to ładnie z UITableView, ale oficjalnie UICollectionView nie ma tego rodzaju delegowanych metod.

Jakieś pomysły? Dzięki!

+4

Tak z ciekawości: dlaczego dequeueReusableCellWithReuseIdentifier: forIndexPath: nie wystarcza? Czy to nie jest już leniwe ładowanie? Myślałem, że komórka zostanie wyświetlona zaraz po tej metodzie. – Masa

+1

@Masa to "rodzaj" leniwego ładowania, ale wyobraź sobie, że masz pełny ekran o rozdzielczości 2208x1242 pikseli i chcesz zezwolić tylko na jedno połączenie http do widocznego obrazu. 'cellForItemAtIndexPath' byłby uruchamiany wielokrotnie, w zasadzie jest to wstępne pobieranie, a nie leniwe ładowanie. FYI: ten uczestnik jest dostępny w ios8 https://developer.apple.com/library/IOs/documentation/UIKit/Reference/UICollectionViewDelegate_protocol/index.html#//apple_ref/occ/intfm/UICollectionViewDelegate/collectionView:willDisplayCell:forItemAtIndexPath: –

Odpowiedz

10

FYI, został dodany do API dla iOS 8:

- (void)collectionView:(UICollectionView *)collectionView willDisplayCell:(UICollectionViewCell *)cell forItemAtIndexPath:(NSIndexPath *)indexPath NS_AVAILABLE_IOS(8_0); 
+3

Oficjalna dokumentacja jest bardzo myląca. Zobacz, co mówią pod dyskusją 'Dyskusja Widok kolekcji wywołuje tę metodę przed dodaniem komórki do jej zawartości. Ta metoda służy do wykrywania dodawania komórek, w przeciwieństwie do monitorowania samej komórki, aby zobaczyć, kiedy się pojawi. " Czekaj, co? Więc nie jest notyfikowane na willDisplay? –

+0

Można tego użyć do skonfigurowania komórki przed wyświetlaniem w systemie iOS 8+. Nie zostanie wywołany w systemie iOS 7 i wcześniejszym. – buildsucceeded

0

robię coś takiego w cellForItemAtIndexPath: (dla leniwych ładowanie obrazów):

  • Jeśli mój model ma obrazu, wystarczy ustawić obraz komórki do niego
  • Jeśli model nie ma obraz, akcja obciążeniu asynchronicznym
  • po zakończeniu obciążenia, sprawdzenie, czy oryginalny indexPath jest nadal widoczny
  • Jeśli tak, zadzwoń cellForItemAtIndexPath dla oryginalnego indexPath. Ponieważ obraz już istnieje w modelu, obraz komórki zostanie teraz ustawiony.

wygląda następująco:

- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath { 

    PhotoCell * cell = [collectionView dequeueReusableCellWithReuseIdentifier:@"PhotoCell" forIndexPath:indexPath]; 
id imageItem = [self.photoSet objectAtIndex:indexPath.row]; 
     ImageManager * listingImage = (ImageManager *)imageItem; 
     if(listingImage.image){ 
      cell.image = listingImage.image; 
     } else { 
      [listingImage loadImage:^(UIImage *image) { 
       [collectionView reloadItemsAtIndexPaths:@[indexPath]]; 
       dispatch_async(dispatch_get_main_queue(), ^{ 
        if ([[collectionView indexPathsForVisibleItems] containsObject:indexPath]) { 
         [(PhotoCell *)[collectionView cellForItemAtIndexPath:indexPath] setImage:image]; 
        } 
       }); 
      }]; 
     } 
    } 

    return cell; 
} 
0

Można skorzystać z SDWebImagehttps://github.com/rs/SDWebImage dla leniwego ładowania. Możesz użyć tego skutecznie z UICollectionView.


- (UICollectionViewCell *)collectionView:(UICollectionView *)cv cellForItemAtIndexPath:(NSIndexPath *)indexPath { 

/*--------- 
----Other CollectiveView stuffs------ 
-----------------*/ 
if([[NSFileManager defaultManager] fileExistsAtPath:YOUR_FILE_PATH isDirectory:NO]) 
{ 
     imagView.image=[UIImage imageWithContentsOfFile:YOUR_FILE_PATH]; 
} 
else 
{ 
    UIActivityIndicatorView *act=[[UIActivityIndicatorView alloc]initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleGray]; 
    [imagView addSubview:act]; 
    act.center=CGPointMake(imagView.frame.size.width/2, imagView.frame.size.height/2); 
    [act startAnimating]; 

    __weak typeof(UIImageView) *weakImgView = imagView; 
    [imagView setImageWithURL:[NSURL URLWithString:REMOTE_FILE_PATH] completed:^(UIImage *image, NSError *error, SDImageCacheType cacheType){ 
    for(UIView *dd in weakImgView.subviews) 
    { 
     if([dd isKindOfClass:[UIActivityIndicatorView class]]) 
     { 
      UIActivityIndicatorView *act=(UIActivityIndicatorView *)dd; 
      [act stopAnimating]; 
      [act removeFromSuperview]; 
     } 
    } 
    NSString *extension=[YOUR_FILE_PATH pathExtension]; 

    [self saveImage:image withFileName:YOUR_FILE_PATH ofType:extension]; 
    }]; 
} 
} 
0

Mam podobną sytuację, gdy trzeba znać ścieżkę indeksu komórki, która ma być wyświetlana. Zakończone - (void)collectionView:(UICollectionView *)collectionView didEndDisplayingCell:(UICollectionViewCell *)cell forItemAtIndexPath:(NSIndexPath *)indexPath. Prawdopodobnie jeden z nich to "didEndDisplaying", a drugi to "willDisplayed".

+1

W rzeczywistości jest zupełnie inaczej. willDisplayCell zostanie wywołany tuż przed wyświetleniem komórki na ekranie. didEndDisplayingCell uruchamia się z chwilą zniknięcia komórki na ekranie. Oznacza to, że jeśli użyjesz didEndDiplayingCell, nie możesz wykonać nieskończonego przewijania, wykrywając ostatnią komórkę, ponieważ użytkownik będzie musiał ją wyświetlić, a następnie przewiń w górę tyle, aby zniknął, aby załadować nowe elementy. Niezbyt przyjazny dla użytkownika, prawda? – CyberDandy

+0

przełączyłem się na metody takie jak wykrywanie, czy UIScrollView trafił w dół – BabyPanda