2012-11-05 1 views
18

In ogni caso, effettuare l'hacking in UICollectionView per chiamare il metodo delegato willDisplayCell quando si visualizza la cella?UICollectionView willDisplayCell metodo delegato?

Ho bisogno di questo per il caricamento lazy, e lo sto facendo bene con UITableView, ma UICollectionView ufficialmente non ha quel tipo di metodo delegato.

Quindi, qualche idea? Grazie!

+4

Solo per curiosità: perché è dequeueReusableCellWithReuseIdentifier: forIndexPath: non è sufficiente? Non è già un carico pigro? Ho pensato che la cella verrà visualizzata subito dopo questo metodo. – Masa

+1

@Masa è una sorta di "caricamento lento", ma immagina di avere un'immagine a schermo intero a 2208x1242 pixel e si desidera consentire solo una connessione http all'immagine visibile. 'cellForItemAtIndexPath' sparerebbe più volte, è fondamentalmente un prefetch, non un caricamento lento. Cordiali saluti: questo delegato è disponibile in ios8 https://developer.apple.com/library/IOs/documentation/UIKit/Reference/UICollectionViewDelegate_protocol/index.html#//apple_ref/occ/intfm/UICollectionViewDelegate/collectionView:willDisplayCell:forItemAtIndexPath: –

risposta

10

Cordiali saluti, questo è stato aggiunto alla API per iOS 8:

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

La documentazione ufficiale è estremamente confusa. Guarda cosa dicono in discussione 'Discussione La vista raccolta chiama questo metodo prima di aggiungere una cella al suo contenuto. Usa questo metodo per rilevare le aggiunte cellulari, invece di monitorare la cella stessa per vedere quando appare. Aspetta, cosa? Quindi non è stato notificato su willDisplay? –

+0

Questo può essere usato per configurare una cella prima della visualizzazione su iOS 8+. Non sarà chiamato su iOS 7 e precedenti. – buildsucceeded

0

che sto facendo qualcosa di simile in cellForItemAtIndexPath: (per le immagini lazy loading):

  • Se il mio modello ha l'immagine, è sufficiente impostare l'immagine del cellulare ad esso
  • Se il modello non dispone di un immagine, calcio di un carico asincrono
  • Al termine del caricamento, controllare se il indexPath originale è ancora visibile
  • In tal caso, chiamare cellForItemAtIndexPath per il indexPath originale. Poiché l'immagine ora esiste nel modello, l'immagine della cella verrà ora impostata.

appare come questa

- (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

si può fare uso di SDWebImagehttps://github.com/rs/SDWebImage per caricamento pigro. È possibile utilizzare questo efficacemente con 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

Ho una situazione simile quando ho bisogno di conoscere il percorso dell'indice di cellula che sta per essere visualizzato. Finito con - (void)collectionView:(UICollectionView *)collectionView didEndDisplayingCell:(UICollectionViewCell *)cell forItemAtIndexPath:(NSIndexPath *)indexPath. Assumibilmente, uno è "didEndDisplaying", un altro è "willDisplayed".

+1

In realtà, è completamente diverso. willDisplayCell viene attivato proprio prima che il rendering della cella venga visualizzato sullo schermo. didEndDisplayingCell viene attivato proprio nel momento in cui la cella scompare per lo schermo. Ciò significa che se si utilizza didEndDiplayingCell, non è possibile effettuare uno scorrimento infinito rilevando l'ultima cella, in quanto l'utente dovrebbe visualizzarla e scorrere verso l'alto quanto basta affinché scompaia per poter caricare nuovi elementi. Non proprio facile da usare, giusto? – CyberDandy

+0

Sono passato a metodi come rilevare se UIScrollView ha raggiunto il fondo – BabyPanda