我正在尝试让表格 View 单元格能够自动调整图像大小来工作。基本上我希望单元格中的图像宽度始终相同,并且高度根据图像的长宽比而变化。
我创建了一个单元格类,它只有标签、imageView 和图像高度的 NSLayoutConstraint 的导出。我有一些异步方法来下载图像并将其设置为单元格 imageView 的图像。然后调用完成句柄,并运行以下代码将高度约束调整为正确的高度:
cell.cellPhoto.loadImageFromURL(url: photos[indexPath.row].thumbnailURL, completion: {
// Set imageView height to the width
let imageSize = cell.cellPhoto.image?.size
let maxHeight = ((self.tableView.frame.width-30.0)*imageSize!.height) / imageSize!.width
cell.cellPhotoHeight.constant = maxHeight
cell.layoutIfNeeded()
})
return cell
这是我编写的加载图像的 UIImageView 扩展:
func loadImageFromURL(url: String, completion: @escaping () -> Void) {
let url = URL(string: url)
makeDataRequest(url: url!, completion: { data in
DispatchQueue.main.async {
self.image = UIImage(data: data!)
completion()
}
})
}
以及它调用的 makeDataRequest 函数:
func makeDataRequest(url: URL, completion: @escaping (Data?) -> Void) {
let session = URLSession.shared
let task = session.dataTask(with: url, completionHandler: { data, response, error in
if error == nil {
let response = response as? HTTPURLResponse
switch response?.statusCode {
case 200:
completion(data)
case 404:
print("Invalid URL for request")
default:
print("Something else went wrong in the data request")
}
} else {
print(error?.localizedDescription ?? "Error")
}
})
task.resume()
}
这适用于框架外的所有单元格,但框架内单元格中的 ImageView 很小。只有当我向下滚动然后再次向上滚动时,它们的大小才能正确。我该如何解决?我知道其他人也遇到过这个问题,但尝试修复却没有效果。
最佳答案
我必须重新创建问题才能了解发生了什么。基本上你需要重新加载表格 View 。当图片下载完成时我会这样做。
在具有 TableView 变量的 View Controller 中。将其添加到 viewDidLoad()
函数中。
override func viewDidLoad() {
super.viewDidLoad()
tableView.delegate = self
tableView.dataSource = self
//Create a notification so we can update the list from anywhere in the app. Good if you are calling this from an other class.
NotificationCenter.default.addObserver(self, selector: #selector(loadList), name: NSNotification.Name(rawValue: "loadList"), object: nil)
}
//This function updates the cells in the table view
@objc func loadList(){
//load data here
self.tableView.reloadData()
}
现在,当照片下载完成后,您可以使用以下命令通知 View Controller 重新加载表格 View ,
func loadImageFromURL(url: String, completion: @escaping () -> Void) {
let url = URL(string: url)
makeDataRequest(url: url!, completion: { data in
DispatchQueue.main.async {
self.image = UIImage(data: data!)
completion()
//This isn't the best way to do this as, if you have 25+ pictures,
//the list will pretty much freeze up every time the list has to be reloaded.
//What you could do is have a flag to check if the first 'n' number of cells
//have been loaded, and if so then don't reload the tableview.
//Basically what I'm saying is, if the cells are off the screen who cares.
NotificationCenter.default.post(name: NSNotification.Name(rawValue: "loadList"), object: nil)
}
})
}
我的代码如下,我没有像你那样做调整大小比率的事情,但同样的想法适用。这就是重新加载 TableView 的方式。另外,我个人不喜欢编写自己的下载代码,包括状态代码和所有内容。这并不有趣,既然别人已经做到了,为什么还要重新发明轮子呢?
Podfile
pod 'SDWebImage', '~> 5.0'
mCell.swift
class mCell: UITableViewCell {
//This keeps track to see if the cell has been already resized. This is only needed once.
var flag = false
@IBOutlet weak var cellLabel: UILabel!
@IBOutlet weak var cell_IV: UIImageView!
override func awakeFromNib() { super.awakeFromNib() }
}
<强> viewController.swift (点击查看完整代码) 我将在这里重点介绍代码。
//Set the image based on a url
//Remember this is all done with Async...In the backgorund, on a custom thread.
mCell.cell_IV.sd_setImage(with: URL(string: ViewController.cell_pic_url[row])) { (image, error, cache, urls) in
// If failed to load image
if (error != nil) {
//Set to defult
mCell.cell_IV.image = UIImage(named: "redx.png")
}
//Else we got the image from the web.
else {
//Set the cell image to the one we downloaded
mCell.cell_IV.image = image
//This is a flag to reload the tableview once the image is done downloading. I set a var in the cell class, this is to make sure the this is ONLY CALLED once. Otherwise the app will get stuck in an infinite loop.
if (mCell.flag != true){
DispatchQueue.main.asyncAfter(deadline: .now() + 0.025){ //Nothing wrong with a little lag.
NotificationCenter.default.post(name: NSNotification.Name(rawValue: "loadList"), object: nil)
mCell.flag = true
}
}
}
}
关于swift - 在表格 View 中的单元格内自动布局图像。布局正确,但只能向下和向后滚动一次?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59722227/