下载图像后重新加载视图中的单元格

时间:2019-06-18 13:22:34

标签: swift xcode

我目前正在学习快速。我在android上有经验,但是现在是时候尝试一些新东西了。我从基础知识开始,将电影数据库从API加载到表中。滚动时,我将下载的海报存储在Movie类中(也下载了它们),我可以看到这些海报,但是下载后视图中的当前单元格只有在滚动后才更新。如何在电影中实现callback到表格视图,以在下载后更新可见的单元格。

电影:

import UIKit
let URL_PREFIX = "https://image.tmdb.org/t/p/original"

class Movie {

let movieId: CLong?
let title: String?
let posterPath: String?
let overview: String?
let releaseDate: String?
var posterImage: UIImage?
var callback: ((_ id: Int) -> Void)?

init(movieId: CLong,title: String,posterPath: String,overview: String,releaseDate: String,posterImage: UIImage?=nil) {

    self.movieId = movieId
    self.title = title
    self.posterPath = posterPath
    self.overview = overview
    self.releaseDate = releaseDate
    self.posterImage = posterImage

    setResizedImage(path: posterPath)

}

func setResizedImage(path: String)
{
    let conPath = URL_PREFIX + path
    print("Path: \(conPath)")

    guard let urlPath = URL(string: conPath) else {
        print("You fucked up")
        return
    }


    print("Download Started")
    getData(from: urlPath) { data, response, error in
        guard let _ = data, error == nil else { return }
        print(response?.suggestedFilename ?? urlPath.lastPathComponent)
        print("Download Finished")

        //update

        DispatchQueue.main.async()
            {

              self.posterImage = UIImage(data: data!)

        }
    }
  }
}

MyViewController:

import UIKit
let URL_MOVIES = "https://api.themoviedb.org/3/movie/upcoming? 
api_key=000";

class DataViewController: UIViewController,UITableViewDelegate, 
UITableViewDataSource {
@IBOutlet weak var myTable: UITableView!
var movieArray :[Movie] = []

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

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

    guard let cell = tableView.dequeueReusableCell(withIdentifier: "MovieTableViewCell", for: indexPath) as? CustomTableViewCell  else {
        fatalError("The dequeued cell is not an instance of MovieTableViewCell.")
    }

    let movie = movieArray[indexPath.row]

    cell.title.text = movie.title
    cell.releaseDate.text = movie.releaseDate
    cell.overview.text = movie.overview

    //cell.url.text = movie.overview

    if (movie.posterImage==nil)
    {
        print("Loaded placeholder")
        cell.poster.image = UIImage(named: "poster")
    }
    else
    {
        print("Hello2")
         cell.poster.image = movie.posterImage
    }

    return cell
}

func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
    print("You tapped cell number \(indexPath.row).")
}

override func viewDidLoad() {
    super.viewDidLoad()

    myTable.rowHeight = UITableView.automaticDimension
    myTable.estimatedRowHeight = 50

    getJsonFromUrl()

}



func getJsonFromUrl(){
    let url = NSURL(string: URL_MOVIES)

    URLSession.shared.dataTask(with: (url as URL?)!, completionHandler: {(data, response, error) -> Void in

        if let jsonObj = try? JSONSerialization.jsonObject(with: data!, options: .allowFragments) as? NSDictionary {

            if let resultArray = jsonObj.value(forKey: "results") as? NSArray
            {
                for film in resultArray
                {

                    if let movieDict = film as? NSDictionary
                    {

                        //getting the name from the dictionary
                        let id = movieDict.value(forKey: "id")
                        let title = movieDict.value(forKey: "title")
                        let posterPath = movieDict.value(forKey: "poster_path")
                        let overview = movieDict.value(forKey: "overview")
                        let releaseDate = movieDict.value(forKey: "release_date")


                        let movie = Movie(movieId:id as! CLong, title: title as! String, posterPath: posterPath as! String, overview: overview as! String, releaseDate: releaseDate as! String)

                        self.movieArray.append(movie)
                    }
                }
            }

            OperationQueue.main.addOperation({

                self.myTable.reloadData()
            })
        }
    }).resume()
  }
}

1 个答案:

答案 0 :(得分:3)

您可以在单元格自定义类中添加下载功能并在回调中分配imageView,但这存在许多问题,例如滚动时多次重新下载同一图像,最好使用SDWebImage或可以使用Kingfisher Library

import SDWebImage

cell.poster.sd_setImage(with: URL(string:movie.imageUrlStr), placeholderImage: UIImage(named: "placeholder.png"))