我对 swift 非常陌生,需要一些帮助来从 URL 中获取图像并将它们存储到字典中以引用到 UITableView。我检查了各种线程,但找不到满足特定需求的场景。
我目前将字典中的产品名称作为键,并将图像 URL 链接到每个名称:
let productLibrary = ["roduct name 1":"http://www.website.com/image1.jpg",
"roduct name 2":"http://www.website.com/image2.jpg"]
我需要将实际图像放入具有相同产品名称的字典中,作为添加到 UITableView 的键。
我目前使用以下代码直接在 tableView cellForRowAt 函数中加载图像,但这会使表格 View 无响应,因为它会在每次 TableView 刷新时加载图像:
cell.imageView?.image = UIImage(data: try! Data(contentsOf: URL(string:
productLibrary[mainPlaces[indexPath.row]]!)!))
mainPlaces 是 productLibrary 字典中列出的一系列产品的数组。最初在字典中预先加载图像肯定会减少加载时间并使 UITableView 像我需要的那样响应。
任何帮助将不胜感激!
@Samarth,我已经按照下面的建议实现了你的代码(只是将扩展直接复制到 ViewController 类上方的 ViewController.swift 文件的根目录中。
其余的,我已经粘贴在 ViewController 类的下面,但它实际上仍然没有在 tableview 中显示图像。
我已尝试完全按照您的建议进行操作,但也许我遗漏了一些明显的东西。很抱歉有很多回复,但我似乎无法让它工作。请在下面查看我的确切代码:
internal func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = UITableViewCell(style: UITableViewCellStyle.default, reuseIdentifier: "Cell")
cell.textLabel?.text = mainPlaces[indexPath.row]
downloadImage(url: URL(string: productLibrary[mainPlaces[indexPath.row]]!)!)
cell.imageView?.downloadedFrom(link: productLibrary[mainPlaces[indexPath.row]]!)
return cell
}
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
performSegue(withIdentifier: "roductSelect", sender: nil)
globalURL = url[mainPlaces[indexPath.row]]!
}
func getDataFromUrl(url: URL, completion: @escaping (_ data: Data?, _ response: URLResponse?, _ error: Error?) -> Void) {
URLSession.shared.dataTask(with: url) {
(data, response, error) in
completion(data, response, error)
}.resume()
}
func downloadImage(url: URL) {
print("Download Started")
getDataFromUrl(url: url) { (data, response, error) in
guard let data = data, error == nil else { return }
print(response?.suggestedFilename ?? url.lastPathComponent)
print("Download Finished")
DispatchQueue.main.async() { () -> Void in
// self.imageView.image = UIImage(data: data)
/* If you want to load the image in a table view cell then you have to define the table view cell over here and then set the image on that cell */
// Define you table view cell over here and then write
let cell = UITableViewCell(style: UITableViewCellStyle.default, reuseIdentifier: "Cell")
cell.imageView?.image = UIImage(data: data)
}
}
}
您可以在项目中同步或异步加载图像。
同步:表示你的数据正在主线程上加载,所以在你的数据被加载之前,你的主线程(UI Thread)将被阻塞。这就是您的项目中正在发生的事情
异步:表示您的数据正在加载到不同于 UI 线程的其他线程上,因此 UI 不会被阻塞,并且您的数据加载是在后台完成的。
试试这个例子来异步加载图像:
异步:
使用完成处理程序创建一个方法以从您的 url 获取图像数据
func getDataFromUrl(url: URL, completion: @escaping (_ data: Data?, _ response: URLResponse?, _ error: Error?) -> Void) {
URLSession.shared.dataTask(with: url) {
(data, response, error) in
completion(data, response, error)
}.resume()
}
创建下载图片的方法(启动任务)
func downloadImage(url: URL) {
print("Download Started")
getDataFromUrl(url: url) { (data, response, error) in
guard let data = data, error == nil else { return }
print(response?.suggestedFilename ?? url.lastPathComponent)
print("Download Finished")
DispatchQueue.main.async() { () -> Void in
// self.imageView.image = UIImage(data: data)
/* If you want to load the image in a table view cell then you have to define the table view cell over here and then set the image on that cell */
// Define you table view cell over here and then write
// cell.imageView?.image = UIImage(data: data)
}
}
}
用法:
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
print("Begin of code")
if let checkedUrl = URL(string: "your image url") {
imageView.contentMode = .scaleAspectFit
downloadImage(url: checkedUrl)
}
print("End of code. The image will continue downloading in the background and it will be loaded when it ends.")
}
扩展:
extension UIImageView {
func downloadedFrom(url: URL, contentMode mode: UIViewContentMode = .scaleAspectFit) {
contentMode = mode
URLSession.shared.dataTask(with: url) { (data, response, error) in
guard
let httpURLResponse = response as? HTTPURLResponse, httpURLResponse.statusCode == 200,
let mimeType = response?.mimeType, mimeType.hasPrefix("image"),
let data = data, error == nil,
let image = UIImage(data: data)
else { return }
DispatchQueue.main.async() { () -> Void in
self.image = image
}
}.resume()
}
func downloadedFrom(link: String, contentMode mode: UIViewContentMode = .scaleAspectFit) {
guard let url = URL(string: link) else { return }
downloadedFrom(url: url, contentMode: mode)
}
}
用法:
imageView.downloadedFrom(link: "image url")
关于您的问题
在表格 View 单元格中加载图像时执行此操作:
cell.imageView?.downloadedFrom(link: productLibrary[mainPlaces[indexPath.row]]! )
关于ios - 如何使用 swift 3.1 将图像从 url 加载到字典中作为数据,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45194878/
欢迎光临 OStack程序员社区-中国程序员成长平台 (https://ostack.cn/) | Powered by Discuz! X3.4 |