我正在嘗試將包含影像的資料從一個視圖控制器發送到另一個。資料是從 API 獲取的。資料已成功加載到第一個視圖控制器中,包括影像,但是當我嘗試使用 didSelectRow 函式重用相同的代碼時,出現以下錯誤。 無法分配“資料”型別的值?輸入 'UIImage'。此行 dc.imagemovie = presenter.getImageData(by: row) 上的錯誤。 這是從 API 獲取資料的代碼。
class MoviePresenter: MoviePresenterProtocol {
private let view: MovieViewProtocol
private let networkManager: NetworkManager
private var movies = [Movie]()
private var cache = [Int: Data]()
var rows: Int {
return movies.count
}
init(view: MovieViewProtocol, networkManager: NetworkManager = NetworkManager()) {
self.view = view
self.networkManager = networkManager
}
func getMovies() {
let url = "https://api.themoviedb.org/3/movie/popular?language=en-US&page=3&api_key=6622998c4ceac172a976a1136b204df4"
networkManager.getMovies(from: url) { [weak self] result in
switch result {
case .success(let response):
self?.movies = response.results
self?.downloadImages()
DispatchQueue.main.async {
self?.view.resfreshTableView()
}
case .failure(let error):
DispatchQueue.main.async {
self?.view.displayError(error.localizedDescription)
}
}
}
}
func getTitle(by row: Int) -> String? {
return movies[row].originalTitle
}
func getOverview(by row: Int) -> String? {
return movies[row].overview
}
func getImageData(by row: Int) -> Data? {
return cache[row]
}
private func downloadImages() {
let baseImageURL = "https://image.tmdb.org/t/p/w500"
let posterArray = movies.map { "\(baseImageURL)\($0.posterPath)" }
let group = DispatchGroup()
group.enter()
for (index, url) in posterArray.enumerated() {
networkManager.getImageData(from: url) { [weak self] data in
if let data = data {
self?.cache[index] = data
}
}
}
group.leave()
group.notify(queue: .main) { [weak self] in
self?.view.resfreshTableView()
}
}
}
這是視圖控制器中的代碼,用于將資料顯示到表視圖單元格中。
class MovieViewController: UIViewController {
@IBOutlet weak var userName: UILabel!
@IBOutlet weak var tableView: UITableView!
private var presenter: MoviePresenter!
var finalname = ""
override func viewDidLoad() {
super.viewDidLoad()
userName.text = "Hello: " finalname
setUpUI()
// configure presenter
presenter = MoviePresenter(view: self)
presenter.getMovies()
}
private func setUpUI() {
tableView.dataSource = self
tableView.delegate = self
}
@IBAction func selectSegment(_ sender: UISegmentedControl) {
if sender.selectedSegmentIndex == 0{
setUpUI()
presenter = MoviePresenter(view: self)
presenter.getMovies()
}
}
}
extension MovieViewController: MovieViewProtocol {
func resfreshTableView() {
tableView.reloadData()
}
func displayError(_ message: String) {
let alert = UIAlertController(title: "Error", message: message, preferredStyle: .alert)
let doneButton = UIAlertAction(title: "Done", style: .default, handler: nil)
alert.addAction(doneButton)
present(alert, animated: true, completion: nil)
}
}
extension MovieViewController: UITableViewDataSource {
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
presenter.rows
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: MovieViewCell.identifier, for: indexPath) as! MovieViewCell
let row = indexPath.row
let title = presenter.getTitle(by: row)
let overview = presenter.getOverview(by: row)
let data = presenter.getImageData(by: row)
cell.configureCell(title: title, overview: overview, data: data)
return cell
}
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
let dc = storyboard?.instantiateViewController(withIdentifier: "MovieDeatilsViewController") as! MovieDeatilsViewController
let row = indexPath.row
dc.titlemovie = presenter.getTitle(by: row) ?? ""
dc.overview = presenter.getOverview(by: row) ?? ""
**dc.imagemovie = presenter.getImageData(by: row)**
self.navigationController?.pushViewController(dc, animated: true)
}
}
extension MovieViewController: UITableViewDelegate {
func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
return UITableView.automaticDimension
}
}
這是顯示資料的代碼。
class MovieDeatilsViewController: UIViewController {
@IBOutlet weak var movieImage: UIImageView!
@IBOutlet weak var movieTitle: UILabel!
@IBOutlet weak var movieOverview: UILabel!
var titlemovie = ""
var overview = ""
var imagemovie = UIImage()
override func viewDidLoad() {
super.viewDidLoad()
movieTitle.text = titlemovie
movieOverview.text = overview
movieImage.image = imagemovie
}
}
uj5u.com熱心網友回復:
您需要回傳 UIImage :
class MoviePresenter: MoviePresenterProtocol {
...
// Convert data to UIImage
func getImageData(by row: Int) -> UIImage? {
return UIImage(data: cache[row])
}
您需要使用 UIImage 和 UIImage 視圖來配置單元格:
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: MovieViewCell.identifier, for: indexPath) as! MovieViewCell
let row = indexPath.row
let title = presenter.getTitle(by: row)
let overview = presenter.getOverview(by: row)
let image = presenter.getImageData(by: row)
// cell is now configured with an image
cell.configureCell(title: title, overview: overview, image: image)
return cell
}
你需要修改 cell.configureCell 來處理 UIImage?而不是資料。
選擇單元格時,您必須使用 UIImage 來初始化 VC:
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
let dc = storyboard?.instantiateViewController(withIdentifier: "MovieDeatilsViewController") as! MovieDeatilsViewController
let row = indexPath.row
dc.titlemovie = presenter.getTitle(by: row) ?? ""
dc.overview = presenter.getOverview(by: row) ?? ""
dc.imagemovie = presenter.getImageData(by: row)// now an image
self.navigationController?.pushViewController(dc, animated: true)
}
使用 UIImage 詳細初始化影像電影 vc :
class MovieDeatilsViewController: UIViewController {
@IBOutlet weak var movieImageView: UIImageView! // Image view here
@IBOutlet weak var movieTitle: UILabel!
@IBOutlet weak var movieOverview: UILabel!
var titlemovie = ""
var overview = ""
var imagemovie : UIImage?
override func viewWillAppear(animated: Bool) {
super.viewWillAppear(animated: animated)
movieTitle.text = titlemovie
movieOverview.text = overview
// here you could also display a default image
// if image is not set
if let image = imagemovie {
movieImageView.image = image
}
}
}
轉載請註明出處,本文鏈接:https://www.uj5u.com/ruanti/427921.html
