2013-01-08 16 views
10

Dopo aver chiamato -[UICollectionView reloadData] ci vuole un po 'di tempo per la visualizzazione delle celle, quindi selezionare un elemento immediatamente dopo aver chiamato reloadData non funziona. C'è un modo per selezionare un elemento immediatamente dopo reloadData?uicollectionview seleziona un elemento immediatamente dopo il ricaricamento?

+0

Eventuali aggiornamenti su questo? Ho lo stesso problema, cercando di creare una selezione durante il caricamento di UICollectionView. –

risposta

2

Lungo le linee di this answer ho trovato che chiamare layoutIfNeeded dopo reloadData sembrava effettivamente 'a filo' la ricarica prima di fare altre cose per la CollectionView:

[self.collectionView reloadData]; 
[self.collectionView layoutIfNeeded]; 
... 

Nella pagina ho trovato questa soluzione, alcuni commentatori hanno indicato che non funziona per loro su iOS 9, ma per me va bene così il tuo chilometraggio può variare.

-3

creare un metodo che esegue la selezione e chiamarlo utilizzando performSelector dopo aver chiamato reload.g.g;

+0

Non mi piace questa soluzione perché richiede una quantità di tempo arbitraria. Come potremmo sapere quando '' 'reloadData''' è finito? Sembra che non ci sia modo di interrogarlo. – mjh

0

Assicurati di chiamare reloadData sul thread principale. Questa potrebbe essere la causa del ritardo nei tuoi aggiornamenti cellulari.

+0

E [la risposta a questa domanda] (http://stackoverflow.com/questions/14804359/uicollectionview-doesnt-update-immediately-when-calling-reloaddata-but-randoml) mostra come farlo. – Jeff

4

Sto gestendo la selezione di celle in collectionView: cellForItemAtIndexPath:. Il problema che ho riscontrato è che se la cella non esisteva, chiamare semplicemente selectItemAtIndexPath: animated: scrollPosition: in realtà non selezionava l'elemento.

Invece si hanno a che fare:

cell.selected = YES;
[m_collectionView selectItemAtIndexPath:indexPath animated:NO scrollPosition:UICollectionViewScrollPositionNone];

3

Non utilizzare reloadData

Usa - (void)performBatchUpdates:(void (^)(void))updates completion:(void (^)(BOOL finished))completion invece. Il blocco di completamento viene eseguito dopo che le animazioni per l'inserimento/la cancellazione delle celle, ecc. Sono state completate. Si può mettere la chiamata a reloadData nel blocco (void (^)(void))updates

+0

Quando UICollectionView ha molti elementi, ho riscontrato ENORME problemi di prestazioni con le chiamate di aggiornamento animate rispetto a reloadData. –

3

Apple dice:

Non si dovrebbe chiamare questo metodo nel mezzo di blocchi di animazione in cui gli elementi vengono inseriti o cancellati. Inserimenti e cancellazioni causano automaticamente l'aggiornamento dei dati della tabella in modo appropriato.

In realtà, non si dovrebbe chiamare questo metodo nel mezzo di un'animazione (compreso lo UICollectionView nello scorrimento).

Quindi, è possibile utilizzare:

[self.collectionView setContentOffset:CGPointZero animated:NO]; 
[self.collectionView performSelectorOnMainThread:@selector(reloadData) withObject:nil waitUntilDone:NO]; 

o contrassegnare sicuri di non qualsiasi animazione, e quindi chiamare reloadData; o

[self.collectionView performBatchUpdates:^{ 
//insert, delete, reload, or move operations 
} completion:nil]; 

Spero che questo è utile a voi.

0

L'ho gestito sul delegato colelctionView di willDisplayCell. L'idea: una variabile temporanea è necessaria per specificare lo scorrimento iniziale già eseguito o meno (scrollIsRequired). Quando verrà visualizzata l'ultima cella visibile, possiamo scorrere fino alla cella richiesta e impostare questa variabile per evitare di scorrere di nuovo.

- (void)collectionView:(UICollectionView *)collectionView willDisplayCell:(UICollectionViewCell *)cell forItemAtIndexPath:(NSIndexPath *)indexPath{ 

    //Perform any configuration 

    if (CGRectGetMaxX(collectionView.frame) <= CGRectGetMaxX(cell.frame)) { 
     // Last visible cell 
     if (self.scrollIsRequired) { 
      [self.collectionView selectItemAtIndexPath:[NSIndexPath indexPathForItem:self.initiallySelectedRepresentativeVerse inSection:0] animated:YES scrollPosition:UICollectionViewScrollPositionLeft]; 
      self.scrollIsRequired = NO; 
     } 
    } 
} 

Ha funzionato per me come un fascino.

1

Il modo Swift:

let selected = collectionView.indexPathsForSelectedItems() 
collectionView.performBatchUpdates({ [weak self] in 
    self?.collectionView.reloadSections(NSIndexSet(index: 0)) 
    }) { completed -> Void in 
     selected?.forEach { [weak self] indexPath in 
      self?.collectionView.selectItemAtIndexPath(indexPath, animated: false, scrollPosition: []) 
     } 
} 
0

Questo è ciò che ha funzionato per me:

ho mantenuto un punto di riferimento del percorso di selezionare l'indice e overide la funzione reloadData:

override func reloadData() { 
    super.reloadData() 
    self.selectItem(at: self.selectedIndexPath, animated: false, scrollPosition: UICollectionViewScrollPosition()) 
} 

Ho provato a fare usando indexPathForSelectedItems, ma è stato la creazione di un infinito loop su caricamento vista raccolta.

Problemi correlati