Caching Images und CollectionViewCells

Diese Seite verwendet Cookies. Durch die Nutzung unserer Seite erklären Sie sich damit einverstanden, dass wir Cookies setzen. Weitere Informationen

  • Caching Images und CollectionViewCells

    Hallo,

    ich habe aktuell ein riesiges caching Problem und weiß nicht so recht weiter. Mein Hauptproblem besteht darin das ich die lokalen Bilder eines Users fetche und diese in eine CollectionViewCell lade.
    Nun fetche ich aber alle Bilder die lokal so rum liegen und ihr könnt euch vorstellen dass das von User zu User teilweise gigantische Zahlen sein können.

    Dadurch das ich manchmal so um die 1000 Bilder fetche braucht die CollectionView dann auch dementsprechend lange um sich zu zeigen und alles anzuzeigen.
    Ich habe natürlich schon im Netz nach Antworten gesucht und bin dabei, was CollectionViews angeht, auf eine Funktion namens prefetchItemsAt gestoßen mit der ich immerhin schon mal die Cells prefetchen kann so das nicht alle Zellen von beginn an existieren.

    Meine Frage wäre nun also wie ich es hinbekomme das nicht alle Bilder auf einmal geladen werden sondern halt Stück für Stück über eine Art prefetching ?


    Aktuell fetche ich über diese Funktion alle Bilder:

    Quellcode

    1. func grabPhotos() {
    2. let imgManager = PHCachingImageManager.default()
    3. let requestOptions = PHImageRequestOptions()
    4. requestOptions.isSynchronous = true
    5. requestOptions.deliveryMode = .highQualityFormat
    6. //Nach Datum ordnen
    7. let fetchOptions = PHFetchOptions()
    8. fetchOptions.sortDescriptors = [NSSortDescriptor(key: "creationDate", ascending: false)]
    9. fetchResult = PHAsset.fetchAssets(with: fetchOptions)
    10. print(fetchResult)
    11. if fetchResult.count > 0 {
    12. for i in 0..<fetchResult.count {
    13. imgManager.requestImage(for: fetchResult.object(at: i) , targetSize: CGSize(width: 200, height: 200), contentMode: .aspectFill, options: requestOptions, resultHandler: {
    14. image, error in
    15. self.imageArray.append(image!)
    16. })
    17. }
    18. } else {
    19. print("You got no photos")
    20. self.collectionView.reloadData()
    21. }
    22. }
    Alles anzeigen


    Desweiteren habe ich mich auch schon mal mit startCachingImages beschäftigt und eine Funktion dazu geschrieben die in der ViewDidAppear() aufgerufen wird:


    Quellcode

    1. func startCachingImages() {
    2. let imgManager = PHCachingImageManager()
    3. let requestOptions = PHImageRequestOptions()
    4. requestOptions.isSynchronous = true
    5. requestOptions.deliveryMode = .highQualityFormat
    6. //Nach Datum ordnen
    7. let fetchOptions = PHFetchOptions()
    8. fetchOptions.sortDescriptors = [NSSortDescriptor(key: "creationDate", ascending: false)]
    9. fetchResult = PHAsset.fetchAssets(with: fetchOptions)
    10. let indexSet = IndexSet(0..<fetchResult.count)
    11. imgManager.startCachingImages(for: fetchResult.objects(at: indexSet), targetSize: CGSize(width: 200, height: 200), contentMode: .aspectFill, options: requestOptions)
    12. }
    Alles anzeigen
  • Den PHCachingImageManager solltest Du nicht als lokale Variable, sondern als Property der Klasse verwenden. Du benötigst die erzeugte Instanz des PHCachingImageManagers auch für den Aufruf von requestImage(for:targetSize:contentMode:options:resultHandler:), um dann die gewünschten Bilder abzurufen.

    Die PHImageRequestOptions sollten dann auch als Property der Klasse definiert werden, da diese sowohl bei startCachingImages(for:targetSize:contentMode:options:) als auch bei requestImage(for:targetSize:contentMode:options:resultHandler:) benötigt werden.

    Bei PHImageRequestOptions solltest Du isSynchronous auf false setzen. Die Images werden dann asynchron geladen und der resultHandler von requestImage(for:targetSize:contentMode:options:resultHandler:) wird aufgerufen, sobald das Bild verfügbar ist.

    Ein Beispiel für die Verwendung von PHCachingImageManager gibt es z.B. hier: SamplePhotosApp-Swift.