5

Wie neuzeichnen nicht sichtbare UICollectionViewCell ist bereit für wenn Wiederverwendung auftritt ???Wie kann man nicht sichtbare UICollectionViewCells nach der Rotation wiederherstellen, wenn die Wiederverwendung stattfindet?

Ein Ansatz, an den ich dachte, war per Code in der Funktion prepareForReuse der Layout-Zelle, aber während es funktioniert, ist es nicht optimal, da es mehr Re-Drawing erfordert.

Hintergrund: Müssen drawRect für Zellen nach einer Orientierungsänderung auslösen, die nicht aktuell sichtbar sind, aber pop up verwendet werden und wurden nicht neu gezeichnet, so weit bis jetzt kann ich nur sehen, dass prepareForReuse wäre angemessen. Problem ist, dass ich alle "Wiederverwendungs" -Zellen neu zeichne, während ich wirklich nur diejenigen neu zeichnen möchte, die während der vorherigen Ausrichtungsposition des Geräts erstellt wurden.

ZUSÄTZLICHE INFORMATIONEN: Also zur Zeit ich das tue:

In Viewcontroller:

override func viewWillLayoutSubviews() { 
    // Clear cached layout attributes (to ensure new positions are calculated) 
    (self.cal.collectionViewLayout as! GCCalendarLayout).resetCache() 
    self.cal.collectionViewLayout.invalidateLayout() 

    // Trigger cells to redraw themselves (to get new widths etc) 
    for cell in self.cal?.visibleCells() as! [GCCalendarCell] { 
     cell.setNeedsDisplay() 
    } 

    // Not sure how to "setNeedsDisplay" on non visible cells here? 
} 

im Layout-Zellen-Klasse:

override func prepareForReuse() { 
    super.prepareForReuse() 
    // Ensure "drawRect" is called (only way I could see to handle change in orientation 
    self.setNeedsDisplay() 
    // ISSUE: It does this also for subsequent "prepareForReuse" after all 
    // non-visible cells have been re-used and re-drawn, so really 
    // not optimal 
} 

Beispiel von dem, was in prepareForReuse ohne den Code geschieht über. Snapshot genommen, nachdem eine Orientierungsänderung, und nur nach ein wenig Scrollen nach oben:

enter image description here

+0

Zellen sollten die Ausrichtung nicht kennen müssen.Wenn Sie sie neu zeichnen müssen, wenn sich die Ausrichtung ändert, stellen Sie diese Logik stattdessen in der Sammlungsansicht ein, und lassen Sie dann in der Sammlungsansicht den Zellen mitteilen, ob sie neu zeichnen müssen oder nicht. – Simon

+0

@Simon Ich bin mir nicht sicher in diesem Fall, wie man (vom Kontroller) die Zellen identifiziert, die nicht sichtbar sind (und zurück in das Bild bei der Wiederverwendung erscheint), um "setsNeedsDisplay" auf ihnen aufzurufen? Ich werde einige weitere Details in meiner Frage – Greg

+0

der CellForRow hinzufügen: AtIndexPath: wird aufgerufen, bevor sie sichtbar wird :) – Simon

Antwort

4

Ich glaube, ich habe es jetzt hier:

import UIKit 

@IBDesignable class GCCalendarCell: UICollectionViewCell { 
    var prevBounds : CGRect? 

    override func layoutSubviews() { 
     if let prevBounds = prevBounds { 
      if !((prevBounds.width == bounds.width) && (prevBounds.height == bounds.height)) { 
       self.setNeedsDisplay() 
      } 
     } 
    } 

    override func drawRect(rect: CGRect) { 
     // Do Stuff 
     self.prevBounds = self.bounds 
    } 

} 

Noted diese Überprüfung nicht funktioniert in „prepareForReuse "Zu dieser Zeit hatte die Zelle die Rotation nicht angewendet. Scheint aber in "layoutSubviews" zu funktionieren.

+0

Dies funktioniert, wenn Sie nach der Rotation verschiedene Zellengrößen haben. – deoKasuhal

+0

ja, haben unterschiedliche Zellgrößen, so dass die Zeichnung neu gemacht werden muss, um zu empfangen – Greg

1

Sie können eine Art von Kommunikation zwischen den Zellen und dem View-Controller implementieren, der die Auflistungsansicht enthält (Protokoll und Delegat oder übergebener Block oder sogar direkter Verweis auf den VC). Dann können Sie den View-Controller nach Rotationsänderungen fragen.

Es ist ein bisschen chaotisch, aber wenn Sie eine Art von Rotationsverfolgung in Ihrem View-Controller haben, können Sie das setNeedsDisplay mit einer einfachen if-Anweisung filtern.

0

Ich hatte ähnliche herausgefordert aktualisieren Zellen, die bereits angezeigt wurden und vom Bildschirm entfernt. Während das Durchlaufen von ALLL-Zellen möglicherweise nicht möglich ist, ist das Auffrischen/Durchlaufen von nicht sichtbaren Zellen möglich. Wenn dies Ihr Anwendungsfall ist - dann lesen Sie weiter. Pre - Warnung - wenn Sie diese Art von Code hinzufügen - erklären Sie, warum Sie es tun. Es ist eine Art Anti-Pattern - kann aber helfen, diesen Fehler zu beheben und dabei helfen, Ihre App zu versenden, obwohl unnötige Komplexität hinzugefügt wird. Verwenden Sie dieses nicht an mehreren Stellen in der App.

Jede Sammlungsansichtszelle, die de-initialisiert wurde (vom Bildschirm entfernt und wiederverwendet wird), sollte automatisch abgemeldet werden.

Mitteilung Muster

let kUpdateButtonBarCell = NSNotification.Name("kUpdateButtonBarCell") 

class Notificator { 
    static func fireNotification(notificationName: NSNotification.Name) { 
      NotificationCenter.default.post(name: notificationName, object: nil) 
    } 
} 

extension UICollectionViewCell{ 
    func listenForBackgroundChanges(){ 
     NotificationCenter.default.removeObserver(self, name: kUpdateButtonBarCell, object: nil) 
     NotificationCenter.default.addObserver(forName:kUpdateButtonBarCell, object: nil, queue: OperationQueue.main, using: { (note) in 

      print(" contentView: ",self.contentView) 

     }) 
    } 
} 



override func collectionView(collectionView: UICollectionView!, cellForItemAtIndexPath indexPath: NSIndexPath!) -> UICollectionViewCell! { 
    let cell = collectionView.dequeueReusableCellWithReuseIdentifier("die", forIndexPath: indexPath) as UICollectionViewCell 
    cell.listenForBackgroundChanges() 
    return cell 
} 


// Where appropriate broadcast notification to hook into all cells past and present 
Notificator.fireNotification(notificationName: kUpdateButtonBarCell) 

Delegierter Muster

Es ist möglich, dies zu vereinfachen .... eine Übung für den Leser. behalte die Zellen einfach nicht bei (nutze eine schwache Verbindung) - sonst hast du Speicherlecks.

Verwandte Themen