在UITableView中滚动时从URL更改加载的图像

时间:2016-12-19 02:25:56

标签: ios swift uitableview firebase firebase-realtime-database

我目前有一个从Firebase加载的tableView。该内容包括一张图片,当用户滚动时,该图片将改变,直到它落在最终图像上。我会假设这会在每个单元格成功加载每个单元格之前为每个单元格分配一个图像,但是却无法提供解决方法。

我必须填充tableView的当前代码如下:

的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
}

数据

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)
        }
    }

}

}

感谢您的帮助!

1 个答案:

答案 0 :(得分:0)

在tableview加载或滚动期间使用异步下载时,这是tableviews的正常行为。您只需在加载前清除图像,并在下载一次图像数据时将其保存在缓存中,以获得高效的网络费用。如果您不使用缓存,tableview将在重新使用单元格时“重新下载”图像。请参阅示例;

 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



}

此代码是从我的项目中复制的。所以我在下载图像时会缓存它。当重复使用单元格时,我也不会重新下载它。只是检查它是否被缓存。因此,您可以将此apporach用于满足您要求的行为。