图像未显示在 UICollectionViewCell 中
Posted
技术标签:
【中文标题】图像未显示在 UICollectionViewCell 中【英文标题】:Images not showing in UICollectionViewCell’s 【发布时间】:2020-03-16 12:18:20 【问题描述】:我正在使用 UIKIT 和 Swift 制作一个 ios 电影应用程序,我想在 collectionview 中显示电影,但是出现了某种故障,并且显示的是某种类型的电影而不是电影。 有人可以帮忙吗?谢谢
moviesViewController.swift
//
// FirstViewController.swift
// PopcornTime
//
// Created by Maxime Ruys on 15/03/2020.
// Copyright © 2020 Pixel-Developers. All rights reserved.
//
import UIKit
import SwiftyJSON
class MoviesViewController: UIViewController, UICollectionViewDataSource, UICollectionViewDelegate
@IBOutlet weak var moviesCollectionView: UICollectionView!
var movies = [Movie]()
override func viewDidLoad()
super.viewDidLoad()
self.moviesCollectionView.delegate = self
self.moviesCollectionView.dataSource = self
fetchMovies()
func fetchMovies()
self.movies = []
let url = URL(string: "API_URL_HERE")
guard let requestUrl = url else fatalError()
var request = URLRequest(url: requestUrl)
request.httpMethod = "GET"
request.httpBody = "".data(using: String.Encoding.utf8)
let task = URLSession.shared.dataTask(with: request) (data, response, error) in
if (error != nil)
print(error)
else
if let data = data, let dataString = String(data: data, encoding: .utf8)
do
if let dataFromString = dataString.data(using: .utf8, allowLossyConversion: false)
let json = try JSON(data: dataFromString)
for(_, movie) in json
var imgs = [String]()
imgs.append(movie["images"]["banner"].stringValue)
imgs.append(movie["images"]["poster"].stringValue)
imgs.append(movie["images"]["fanart"].stringValue)
self.movies.append(Movie(id: movie["_id"].stringValue, title: movie["title"].stringValue, desc: movie["synopsis"].stringValue, playTime: movie["runtime"].stringValue, imgs: imgs))
catch
print(error)
DispatchQueue.main.async
self.moviesCollectionView.reloadData()
task.resume()
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int
return self.movies.count
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "MoviesRowController",
for: indexPath) as! MoviesRowController
cell.moviesRowImg.image = downloadImage(from: URL(string: movies[indexPath.row].imgs[0])!)
cell.moviesTitleLbl.text = movies[indexPath.row].title
return cell
func downloadImage(from url: URL) -> UIImage
getData(from: url) data, response, error in
guard let data = data, error == nil else return
DispatchQueue.main.async()
return UIImage(data: data)
return UIImage(named: "test")!
func getData(from url: URL, completion: @escaping (Data?, URLResponse?, Error?) -> ())
URLSession.shared.dataTask(with: url, completionHandler: completion).resume()
collectionview 故障图像:
collectionview 属性:
colletionview 单元格属性:
【问题讨论】:
从网址下载后,请检查您是否获得了正确的图像。在return UIImage(data: data)
中放置一个断点,看看会发生什么。
@iPeter 我已经尝试使用普通图像,它仍然会显示三角形。
如果您在图像数组中有图像 URL,那么 SDWebImage 会对您有很大帮助。检查此链接:github.com/SDWebImage/SDWebImage
【参考方案1】:
你不能分配一个异步的值,所以这里的 return 是 nil
func downloadImage(from url: URL) -> UIImage
getData(from: url) data, response, error in
guard let data = data, error == nil else return
DispatchQueue.main.async()
return UIImage(data: data)
return UIImage(named: "test")
使用SDWebImage
【讨论】:
【参考方案2】:你可以像下面这样进行自省。
if movies[indexPath.row].imgs.count>0, let url = URL(string: movies[indexPath.row].imgs[0]!)
如果您希望缓存图像以避免多次请求,请使用以下扩展。
let imageCache = NSCache<NSString, UIImage>()
extension UIImageView
func imageFromServerURL(_ URLString: String, placeHolder: UIImage?)
self.image = nil
if let cachedImage = imageCache.object(forKey: NSString(string: URLString))
self.image = cachedImage
return
if let url = URL(string: URLString)
URLSession.shared.dataTask(with: url, completionHandler: (data, response, error) in
//print("RESPONSE FROM API: \(response)")
if error != nil
print("ERROR LOADING IMAGES FROM URL: \(error)")
DispatchQueue.main.async
self.image = placeHolder
return
DispatchQueue.main.async
if let data = data
if let downloadedImage = UIImage(data: data)
imageCache.setObject(downloadedImage, forKey: NSString(string: URLString))
self.image = downloadedImage
).resume()
【讨论】:
感谢这至少解决了三角形。但单元格的大小与必须的不同。 这将多次下载图像,可能同时您需要现金使用SDwebimage
,正如我在我的回答中所说的那样
@navroz 起初它可以工作,但现在它给了我一个致命错误,并说在我添加代码行来注册我的单元格后图像为零。 ibb.co/x3Qm5Dwibb.co/Cw0bQjn
首先您需要检查哪个值是 nil 以防 imgs[0] 导致它,然后您必须对其进行检查。在编辑的答案中提到。否则,您在配置单元格时做错了。【参考方案3】:
您的手机也未注册:
self.collectionView.register(UICollectionViewCell.self, forCellReuseIdentifier: "movieCell")
【讨论】:
谢谢,我怎么会忘记这一点。可能是因为过去一年我没有制作任何 iOS 应用程序。谢谢 实际上我不必这样做,否则我会覆盖当前单元格属性,因为我使用的是情节提要,而这次我没有以编程方式进行 aaaah 好的,那么抱歉,我使用以编程方式创建所有视图,但我在代码中错过了它以上是关于图像未显示在 UICollectionViewCell 中的主要内容,如果未能解决你的问题,请参考以下文章
为啥图像未显示在目标 C 的 cellforRowAtIndexPath 中