De cel van UICollectionView verdwijnt

Wat gebeurt er

Momenteel heb ik een applicatie die twee UICollectionViewsgebruikt in een UITableView. Op deze manier creëer ik een Pulse News-achtige applicatie. Mijn probleem hiermee is dat soms de 6e en 11e rij volledig verdwijnt, waardoor er een lege ruimte overblijft waar het de cel zou moeten zijn. Ik zou het eigenlijk niet erg vinden als alle cellen zo waren (en op deze manier kon ik aannemen dat ik de dingen niet goed deed), maar het probleem is dat het gewoon gebeurt met die specifieke cellen.

Mijn theorie

De 6e en 11e rij zijn degene die verschijnen wanneer ik begin te scrollen, dus standaard kan ik 5 cellen zien, en wanneer ik de eerste horizontale scroll doe, verschijnt de 6e (soms lege ruimte).

Wat ik heb

Het enige wat ik op dit moment doe is dit:

[self.collectionView registerNib:[UINib nibWithNibName:CELL_NIB_NAME bundle:nil] forCellWithReuseIdentifier:CELL_IDENTIFIER];

Op de viewDidLoad. En over het maken van de cel:

- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath
{
    MyCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:CELL_IDENTIFIER forIndexPath:indexPath];
    NSMutableDictionary *dictionary = [self.DataSource objectAtIndex:[indexPath row]];
    [cell buildViewWithDictionary:dictionary withReferenceParent:self.referenceViewController];
    return cell;
}

Dus als ik het zeg, er is hier niets bijzonders aan de hand. Ik dacht dat er iets mis was met de gegevensbron (een dummy JSON-bestand), maar soms werkt het goed en wordt de cel weergegeven, dus ik denk dat dat deel in orde is.

Dus mijn “vraag”: weet iemand wat er aan de hand is? Ik zeg niet graag dat het een bug van iOS is, maar ik kan niets anders bedenken.


1.0 bewerken

Het verbazingwekkende is dat deze methode

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

Gaat van indexPath[0,4] naar [0,6] zonder de [0,5] te berekenen. De eerste keer dat ik dit echt zie gebeuren in iOS.


2.0 bewerken

Ik heb de manier veranderd waarop ik de cellen maak, en in plaats van de wachtrij te verwijderen, gebruik ik de oude manier:

NSArray *nib = [[NSBundle mainBundle] loadNibNamed:CELL_NIB_NAME owner:self options:nil];
MyCell *cell = (MyCell *)[nib objectAtIndex:0];

Nog steeds hetzelfde trieste resultaat.


Antwoord 1, autoriteit 100%

Dus, wat werkte er?

1) Subklasse UICollectionViewFlowLayout.

2) Stel de flowLayout van mijn UICollectionViewin op mijn nieuwe subklasse.

3) Stel op de init-methode van de subklasse UICollectionViewFlowLayoutde gewenste richting in:

self.scrollDirection = UICollectionViewScrollDirectionHorizontal;

In mijn geval is het Horizontaal.

4) Het belangrijke deel:

-(BOOL)shouldInvalidateLayoutForBoundsChange:(CGRect)newBounds
{
   return YES;
}

Op dit moment zou ik een beetje moeten theoretiseren, maar eerlijk gezegd heb ik geen idee.


Antwoord 2, autoriteit 45%

De bovenstaande antwoorden werkten niet voor mij, maar na het downloaden van de afbeeldingen heb ik de code vervangen
[self.myCollectionView reloadData]
met
[self.myCollectionView reloadSections:[NSIndexSet indexSetWithIndex:0]];
om de collectieweergave te vernieuwen en het toont alle cellen, je kunt het proberen.


Antwoord 3, autoriteit 21%

Geen van de oplossingen die door iemand zijn gegeven, heeft me geholpen bij mijn aangepaste lay-out die we in onze app nodig hebben.
In plaats daarvan moest ik dit doen: (En ja, HET WERKT!!!)

- (NSArray *)layoutAttributesForElementsInRect:(CGRect)rect{
    CGSize size = [self collectionViewContentSize];
    rect.size.height = size.height*2;
    NSArray *atrributes_Super = [super layoutAttributesForElementsInRect:rect];
    return atrributes_Super;
}

Per slot van rekening zoekt UICollectionView alleen naar de attributen voor de elementen die in de rect van uw scherm moeten worden weergegeven.


Antwoord 4, autoriteit 8%

De tip van Rob over de bug heeft me geholpen. De bug stelt dat als de sectie-invoegingen en de celbreedte en -afstand precies optellen tot de breedte van het scherm, de eerste kolom soms willekeurig verdwijnt en voor sommige cellen op sommige plaatsen weer verschijnt. In plaats van subklassen of de celbreedtes te wijzigen, heb ik de sectie-inzetstukken voor links en rechts in mijn storyboard gewijzigd van 6 in 4 en ik heb het probleem niet meer gezien.


Antwoord 5, autoriteit 3%

In mijn geval (verticale scroll, met cellen die in eerste weergave verdwenen), verdwenen cellen vanwege een onjuiste geschatte grootte. Het lijkt erop dat UICollectionViewde geschatte grootte gebruikt om de items te berekenen die in de eerste weergave moeten worden geladen. Ik had de geschatte grootte te hoog ingesteld, wat resulteerde in verkeerde berekeningen voor het aantal items dat in het eerste scherm moest worden geladen.

Op het moment dat ik de geschatte hoogte een beetje laag maakte, verschenen alle cellen correct.


Antwoord 6, autoriteit 3%

We kwamen onlangs verdwijnende cellen tegen en ontdekten dat in plaats van ‘verborgen’ cellen over te slaan, we per ongeluk cellen van 0x0-formaat invoegden. Het resulterende gedrag was erg verwarrend en suggereerde niet dat deze onzichtbare cellen het probleem waren. We zouden de cellen en de lay-out van de juiste grootte zien, maar een paar van de geldige cellen zouden consequent verdwijnen na het scrollen van/naar het scherm. Ik heb geen idee waarom het vermengen van cellen met een grootte van 0 dit gedrag zou veroorzaken, maar het verwijderen ervan loste het probleem op. Dit is misschien niet de oorzaak van uw probleem, maar dit kan nuttig zijn voor ontwikkelaars die op zoek zijn naar vergelijkbare symptomen.


Antwoord 7, autoriteit 3%

Omdat ik plotseling hetzelfde probleem heb en enige tijd heb besteed aan het uitzoeken van een van de mogelijke redenen voor het verdwijnen van de cel tijdens het scrollen, zal ik ook mijn antwoord toevoegen.

Vereisten voor het probleem:

  1. U heeft een UICollectionViewinstantie
  2. Je hebt een UICollectionViewFlowLayoutSubclass

Het probleem

Cellen verdwijnen uit de collectieweergave nadat ze naar een bepaald punt zijn gescrold.

De oorzaak van het probleem ligt in de verkeerde subclassificatie van de UICollectionViewFlowLayout.

Zoals expliciet vermeld in documentatie:

Elk lay-outobject moet de volgende methoden implementeren:

- collectionViewContentSize
- layoutAttributesForElements(in:)
- layoutAttributesForItem(at:)
- layoutAttributesForSupplementaryView(ofKind:at:) // (if your layout supports -supplementary views)
-layoutAttributesForDecorationView(ofKind:at:) // (if your layout supports decoration views)
- shouldInvalidateLayout(forBoundsChange:)

Door te vertrouwen op UICollectionViewFlowLayoutimplementatie van bovenstaande methoden, missen we het feit dat func layoutAttributesForElements(in rect: CGRect)en collectionViewContentSizezullen genereren verkeerde contentSize(de grootte die correct zou zijn als alle cellen de grootte itemSizezouden hebben en de inhoudsgrootte zou overeenkomen. Zodra je offsetYzal groter zijn dat de cellen in de hoogte van contentSizeallemaal verdwijnen.

De oplossing

De oplossing bevindt zich in de juiste subklasse UICollectionViewFlowLayout. Overschrijf alle methoden die vereist zijn om te overschrijvenen alles zal prima werken.


Antwoord 8

Ik kwam net een probleem tegen waarbij alle UICollectionView-cellen verdwenen bij het scrollen.

Dit gebeurde omdat ik had aangegeven

extension UICollectionViewLayout {
    static let defaultLayout: UICollectionViewLayout {
        let layout = UICollectionViewFlowLayout()
        layout.estimatedItemSize = UICollectionViewFlowLayout.automaticSize
        return layout
    }()
}

… wat betekent dat dezelfde lay-outinstantie in meerdere UICollectionViews werd gebruikt. Het was mijn bedoeling om daar een berekende var van te maken. Ik hoop dat dit iemand helpt die per ongeluk hetzelfde lay-outobject in meerdere verzamelingsweergaven gebruikt.


Antwoord 9

Wat in mijn geval de oorzaak was van het verdwijnen van de cellen, was dat de toewijzing van de gegevensbron voortijdig werd opgeheven. UICollectionView.dataSourceis een zwakke eigenschap, wat betekent dat, tenzij u er een sterke verwijzing naar behoudt, de toewijzing van het object aan het einde van het bereik waarin u hebt gemaakt, wordt opgeheven. Het probleem manifesteerde zich met verdwijnende cellen zodra ik op de UICollectionViewtikte.


Antwoord 10

Voor mij leek dit probleem te maken te hebben met de manier waarop ik mijn collectieweergave aanpas aan een open toetsenbord om overlap van inhoud te voorkomen.

in mijn waarnemer om te reageren op KeyboardWillShow had ik dit:

var userInfo = obj.UserInfo[UIKeyboard.FrameEndUserInfoKey];
if (userInfo is NSValue value)
{
    var rect = value.CGRectValue;
    var windowOffset = this.Superview.ConvertPointToView(this.Frame.Location, UIApplication.SharedApplication.KeyWindow);
    var newHeight = rect.Y - windowOffset.Y;
    this._controller.CollectionView.Frame = new CGRect(0, 0, this._controller.CollectionView.Frame.Width, newHeight);
}

Na dit te hebben gewijzigd:

var userInfo = obj.UserInfo[UIKeyboard.FrameBeginUserInfoKey];
if (userInfo is NSValue value)
{
    var rect = value.CGRectValue;
    UIEdgeInsets contentInsets = new UIEdgeInsets(0, 0, rect.Height, 0);
    this._controller.CollectionView.ContentInset = contentInsets;
    this._controller.CollectionView.ScrollIndicatorInsets = contentInsets;
}

Het probleem met het verdwijnen van cellen is volledig verdwenen. Dit is C# van het werken met xamarin, maar ik hoop dat het iemand anders helpt.


Antwoord 11

Ik denk dat dit geen bug van UICollectionView is, misschien retourneert u niet de juiste gegevens in de - (NSArray *)layoutAttributesForElementsInRect:(CGRect)rectmethode.

Je kunt deze demo bekijken: https://github.com/lqcjdx/YLTagsChooser, allemaal cellen kunnen verschijnen bij het scrollen van de UICollectionView.


Antwoord 12

In mijn geval was het probleem met de verdwijnende cel te wijten aan:
IQKeyboardManager SDK toegevoegd in project.
Omdat deze SDK-animatie voor toetsenbord in het hele project activeert, zelfs als je het niet rechtstreeks aan een gescheiden bestand toevoegt.

Het vreemde voor mij was dat het probleem zich alleen voordoet wanneer u UIEdgeInset toevoegt voor de collectieweergave met in mijn geval hoger dan 40 vanaf .bottom.

Hoe kan ik dit oplossen? U moet het pod-bestand ontgrendelen en toevoegen

DispatchQueue.main.async {}

voor deze animatie.
In het geval van UICollectionViewController zit het erin

@objc internal func keyboardWillHide(_ notification: Notification?) {}

methode met lijn

if let lastScrollView = lastScrollView {}

Als u de hoofdwachtrij toevoegt voor dit animatieprobleem, verdwijnt het probleem.

Other episodes