2016-12-19 4 views
3

Ich habe derzeit eine TabelleView, die von Firebase geladen wird. Dieser Inhalt enthält ein Bild, das sich ändert, wenn der Benutzer scrollt, bis es sich auf seinem endgültigen Bild befindet. Ich würde annehmen, dass dies jeder Zelle ein Bild zuweisen würde, bevor es jede Zelle erfolgreich laden kann, aber nicht in der Lage war, eine Arbeit zu finden.Bilder, die von einer URL geladen wurden, die sich beim Scrollen in UITableView ändert

Der aktuelle Code, den ich die Tableview zu füllen haben, ist wie folgt:

Tableview

import UIKit 
import FirebaseAuth 
import FirebaseStorage 

class Articles: UITableViewController { 

var vcType:String = "Home" 
var rooms = [Room]() 
var articleCell = ArticlesCell() 
@IBOutlet weak var menuButton: UIBarButtonItem! 
override func viewDidLoad() { 
    super.viewDidLoad() 

    if self.vcType == "Home" 
    { 
     self.rooms += ArticlesManager.sharedClient.rooms 
    } 
    else 
    { 
     if let obj = ArticlesManager.sharedClient.catRooms[self.vcType.lowercased()] //as? [Room] 
     { 
      self.rooms += obj 
     } 
    } 
    self.tableView.reloadData() 

    ArticlesManager.sharedClient.blockValueChangeInRoomArray = { 
     newRoom in 
     if self.vcType == "Home" 
     { 
      self.rooms.append(newRoom) 
      self.rooms.sort(by: { 
       if $0.created_Date == nil 
       { 
        return false 
       } 
       if $1.created_Date == nil 
       { 
        return true 
       } 

       return $0.created_Date.compare($1.created_Date) == ComparisonResult.orderedDescending 
      }) 

     } 
     else 
     { 
      if self.vcType.lowercased() == newRoom.category 
      { 
       self.rooms.append(newRoom) 

       self.rooms.sort(by: { 
        if $0.created_Date == nil 
        { 
         return false 
        } 
        if $1.created_Date == nil 
        { 
         return true 
        } 

        return $0.created_Date.compare($1.created_Date) == ComparisonResult.orderedDescending 
       }) 

       self.tableView.reloadData() 

      } 
     } 
    } 

} 

override func numberOfSections(in tableView: UITableView) -> Int { 
    return 1 
} 

override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { 
    return rooms.count 
} 

override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { 

    if (indexPath as NSIndexPath).row == 0 { 
     let cell2 = tableView.dequeueReusableCell(withIdentifier: "featured", for: indexPath) as! featuredCell 
     let room = rooms[(indexPath as NSIndexPath).row] 
     cell2.configureCell(room) 
     return cell2 

    } else { 

     let cell = tableView.dequeueReusableCell(withIdentifier: "Cell", for: indexPath) as! ArticlesCell 
     let room = rooms[(indexPath as NSIndexPath).row] 
     cell.configureCell(room) 
     return cell 
} 

Daten

import Foundation 
import Firebase 
import FirebaseAuth 


let roomRef = FIRDatabase.database().reference() 

class Data { 

static let dataService = Data() 

fileprivate var _BASE_REF = roomRef 
fileprivate var _ROOM_REF_ = roomRef.child("rooms") 

fileprivate var _BASE_REF2 = roomRef 
fileprivate var _ROOM_REF_2 = roomRef.child("contents") 

var BASE_REF: FIRDatabaseReference { 
    return _BASE_REF 
} 

var ROOM_REF: FIRDatabaseReference { 
    return _ROOM_REF_ 
} 

var storageRef: FIRStorageReference { 
    return FIRStorage.storage().reference() 
} 

var fileURL: String! 

func fetchData(_ callback: @escaping (Room) ->()) { 
    Data.dataService.ROOM_REF.observe(.childAdded, with: { (snapshot) in 

     print("snapshot.value - \(snapshot))") 
     let room = Room(key: snapshot.key, snapshot: snapshot.value as! Dictionary<String, AnyObject>) 
     callback(room) 
    }) 
} 


} 

TableViewCell

import UIKit 
import FirebaseStorage 

class featuredCell: UITableViewCell { 


@IBOutlet weak var featuredImage: UIImageView! 
@IBOutlet weak var featuredTitle: UITextView! 
@IBOutlet weak var featuredAuthor: UITextField! 
@IBOutlet weak var featuredDate: UITextField! 

@IBOutlet weak var featuredContent: UITextView! 
class var defaultHeight: CGFloat { get { return ((UIScreen.main.fixedCoordinateSpace.bounds.height - 64)/5) * 3}} 


func configureCell(_ room: Room) { 
    self.featuredTitle.text = room.title 
    self.featuredDate.text = room.date 
    self.featuredAuthor.text = room.author 
    self.featuredContent.text = room.story 
    if let imageURL = room.thumbnail { 
     if imageURL.hasPrefix("gs://") { 
      FIRStorage.storage().reference(forURL: imageURL).data(withMaxSize: INT64_MAX, completion: { (data, error) in 
       if let error = error { 
        print("Error downloading: \(error)") 
        return 
       } 
       self.featuredImage.image = UIImage.init(data: data!) 
      }) 
     } else if let url = URL(string: imageURL), let data = try? Foundation.Data(contentsOf: url) { 
      self.featuredImage.image = UIImage.init(data: data) 
     } 
    } 

} 

} 

Vielen Dank für Ihre Hilfe!

+0

Wenn Sie Zellen erneut verwenden, kann featuredImage.image immer noch mit dem vorherigen Bild geladen werden. Sie sollten sicherstellen, dass Ihre if-else-Bedingung in ConfigureCell alle Fälle abdeckt. Wenn beispielsweise imageURL = room.thumbnail fehlschlägt und keine andere Bedingung vorliegt, wird featuredImage.image weiterhin mit dem vorherigen Bild geladen. – koropok

Antwort

0

Dies ist ein normales Verhalten von Tabellenansichten beim Arbeiten mit asynchronem Herunterladen während des Ladens oder Scrollens von Tabellenansichten. Sie müssen Ihr Bild vor dem Laden löschen und die Bilddaten im Cache behalten, wenn sie einmal heruntergeladen wurden, um eine effiziente Netzwerkgebühr zu erhalten. Wenn Sie kein Caching verwenden, wird das Bild in der Tabellenansicht immer dann erneut heruntergeladen, wenn die Zelle wiederverwendet wird. Bitte beachten Sie das Beispiel;

public func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { 
    let cell = tableView.dequeueReusableCell(withIdentifier: "cell") as! TableViewCell 
    let urle = self.filteredFlats[indexPath.row].flatThumbnailImage?.imageDownloadURL 
    if let url = urle 
    { 
     cell.imgv.image = nil 

     if let imagefromCache = imageCache.object(forKey: url as AnyObject) as? UIImage 
     { 
      cell.imgv.image = imagefromCache 

     } 
     else 
     { 
      cell.imgv.image = nil 
      let urlURL = URL(string: (url)) 

      URLSession.shared.dataTask(with: urlURL!, completionHandler: { (data, response, error) in 
       if error != nil 
       { 
        print(error.debugDescription) 
        return 
       } 
       DispatchQueue.main.async { 
        let imagetoCache = UIImage(data:data!) 
        self.imageCache.setObject(imagetoCache!, forKey: url as AnyObject) 
        cell.imgv.image = imagetoCache 

       } 
      }).resume() 


     } 

    } 

    return cell 



} 

Dieser Code wurde von meinem Projekt kopiert. Also speichere ich das Bild, wenn es bereits heruntergeladen wurde. Außerdem lade ich es nicht erneut herunter, wenn die Zelle wiederverwendet wird. Überprüfen Sie einfach, ob es zwischengespeichert ist oder nicht. So können Sie dieses Verhalten für ein Verhalten nutzen, das Ihren Anforderungen entspricht.

Verwandte Themen