UICollectionView flowLayout non wrapping celle correttamente (iOS)


Answers

ho scoperto problemi simili nella mia applicazione iPhone. La ricerca nel forum di sviluppo di Apple mi ha portato questa soluzione adatta che ha funzionato nel mio caso e probabilmente anche nel tuo caso:

Sottoclasse UICollectionViewFlowLayout e override shouldInvalidateLayoutForBoundsChange per restituire YES .

//.h
@interface MainLayout : UICollectionViewFlowLayout
@end

e

//.m
#import "MainLayout.h"
@implementation MainLayout
-(BOOL)shouldInvalidateLayoutForBoundsChange:(CGRect)newBounds{
    return YES;
}
@end
Question

Ho un UICollectionView con un FLowLayout. Funzionerà come mi aspetto la maggior parte del tempo, ma ogni tanto una delle celle non si avvolge correttamente. Ad esempio, la cella che dovrebbe essere nella prima "colonna" della terza riga se effettivamente segue nella seconda riga e c'è solo uno spazio vuoto dove dovrebbe essere (vedi diagramma sotto). Tutto quello che puoi vedere di questa cella rouge è il lato sinistro (il resto è troncato) e il posto dove dovrebbe essere è vuoto.

Questo non succede in modo coerente; non è sempre la stessa riga. Una volta che è successo, posso scorrere verso l'alto e poi indietro e la cella si sarà riparata da sola. Oppure, quando premo la cella (che mi porta alla vista successiva tramite una spinta) e poi faccio un salto indietro, vedrò la cella nella posizione sbagliata e poi salterà nella posizione corretta.

La velocità di scorrimento sembra semplificare la riproduzione del problema. Quando faccio scorrere lentamente, riesco ancora a vedere la cella nella posizione sbagliata di tanto in tanto, ma poi salterà immediatamente nella posizione corretta.

Il problema è iniziato quando ho aggiunto le sezioni. In precedenza, avevo le celle quasi allineate ai limiti della raccolta (poco o niente) e non ho notato il problema. Ma questo significava che la destra e la sinistra della vista raccolta erano vuote. Vale a dire, non poteva scorrere. Inoltre, la barra di scorrimento non era allineata a destra.

Posso far sì che il problema si verifichi su entrambi i Simulator e su un iPad 3.

Immagino che il problema stia accadendo a causa degli inserti della sezione sinistra e destra ... Ma se il valore è sbagliato, allora mi aspetterei che il comportamento fosse coerente. Mi chiedo se questo potrebbe essere un bug con Apple? O forse questo è dovuto a un accumulo di inset o qualcosa di simile ...

Qualsiasi soluzione / soluzione alternativa è apprezzata.

Follow-up : Ho usato questa risposta di seguito da Nick per oltre 6 mesi 12 mesi e 2 anni senza problemi (nel caso in cui le persone si chiedessero se ci sono buchi in quella risposta - non ne ho ancora trovate). Ben fatto Nick.




Ho aggiunto una segnalazione di bug ad Apple. Ciò che funziona per me è impostare la sezione inferioreInset su un valore inferiore a quello superiore.




Una versione rapida della risposta di Nick Snyder:

class NDCollectionViewFlowLayout : UICollectionViewFlowLayout {
    override func layoutAttributesForElements(in rect: CGRect) -> [UICollectionViewLayoutAttributes]? {
        let attributes = super.layoutAttributesForElements(in: rect)
        let contentSize = collectionViewContentSize
        return attributes?.filter { $0.frame.maxX <= contentSize.width && $0.frame.maxY < contentSize.height }
    }
}



Le risposte di cui sopra non funzionano per me, ma dopo aver scaricato le immagini, ho sostituito

[self.yourCollectionView reloadData]

con

[self.yourCollectionView reloadSections:[NSIndexSet indexSetWithIndex:0]];

per aggiornare e può mostrare tutte le celle correttamente, puoi provarlo.




Ho appena riscontrato un problema simile con le celle che scompaiono dopo lo scorrimento di UICollectionView su iOS 10 (non ho avuto problemi con iOS 6-9).

Sottoclasse di UICollectionViewFlowLayout e metodo di sovrascrittura layoutAttributesForElementsInRect: non funziona nel mio caso.

La soluzione era abbastanza semplice. Attualmente utilizzo un'istanza di UICollectionViewFlowLayout e imposto sia itemSize che EstimateItemSize (non ho utilizzato preventestimeItemSize) e lo ho impostato su alcune dimensioni diverse da zero. La dimensione effettiva sta calcolando in collectionView: layout: sizeForItemAtIndexPath: method.

Inoltre, ho rimosso una chiamata dal metodo invalidateLayout da layoutSubviews per evitare ricariche non necessarie.




Links