UITableViewCell 图像不是全宽

UITableViewCell image not full width

我正在尝试填充一个 UITableView 将图像拉伸到全宽并自动设置它们的高度。我试过将 estimatedHeightForRowAtIndexPathheightForRowAt 设置为 UITableView.automaticDimension,但它们看起来真的很小。

我的 CustomTableViewCell 有一个 UIImage,所有边的约束都设置为 0。

我开始认为这可能与 main.storyboard 是一个包含 UITableView 的 Viewcontroller 有关,它的数据源和委托设置为视图控制器。 main.storyboard 应该是 UITableViewController 吗?

谁能告诉我哪里做错了?

这是目前的样子:

class ViewController: UIViewController {

    @IBOutlet weak var tableView: UITableView!

    private var imageUrls:[String] = ["https://via.placeholder.com/200","https://via.placeholder.com/400","https://via.placeholder.com/600"]

    override func viewDidLoad() {
        super.viewDidLoad()

        tableView.estimatedRowHeight = 320
        tableView.rowHeight = UITableView.automaticDimension

        let textFieldCell = UINib(nibName: "CustomTableViewCell",
                              bundle: nil)
        tableView.register(textFieldCell, forCellReuseIdentifier: "CustomTableViewCell")
    }


}

extension ViewController: UITableViewDataSource {
    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return imageUrls.count
    }

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

        if let cell = tableView.dequeueReusableCell(withIdentifier: "CustomTableViewCell") as? CustomTableViewCell {

            let imageUrl = imageUrls[indexPath.row]
            cell.messageImage.sd_setImage(with: URL(string: imageUrl), placeholderImage: nil , options: SDWebImageOptions(rawValue: 0))

            return cell
        }

        return UITableViewCell()
    }

    func tableView(_ tableView: UITableView, estimatedHeightForRowAtIndexPath indexPath: IndexPath) -> CGFloat {
        return 320
    }

    func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
        return UITableView.automaticDimension
    }
}

编辑:这是图像内容模式设置为纵横比填充时的样子。

我刚刚也注意到一个警告:

[Warning] Warning once only: Detected a case where constraints ambiguously suggest a height of zero for a table view cell's content view. We're considering the collapse unintentional and using standard height instead.

问题是,在单元格创建并绘制到屏幕上之后,您无法更新单元格的高度。但是你可以做的是当你下载一个图像时,你通知 TableView 重新加载图像所属的特定行。这将调用 heightForRowAtIndexPath,但您现在会知道图像的确切高度。

定义一个数组,您将在 ViewController 中存储获取的图像。

private var images: [UIImage] = []

现在,在创建单元格时,您要么将该图像传递给单元格,要么在下载任务中使用回调通知 TableView 重新加载特定行。

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    let cell = tableView.dequeueReusableCell(withIdentifier: "YourCell") as? YourCell

    if images.count > indexPath.row {
        // We have the image, load it
        cell?.setupContentWith(image: images[indexPath.row])
    } else {
        // We do not have the image, download it
        cell?.setupContent(url: URL(string: imageUrls[indexPath.row]), completion: { [weak self] image in
            self?.images.append(image)
            tableView.reloadRows(at: [indexPath], with: .none)
        })
    }
    return cell ?? UITableViewCell()
}

TableViewCell 中的函数可能如下所示:

private func setupContent(url: URL?, completion: @escaping (UIImage) -> Void) {
    guard let url = url else { return }
    yourImageView?.downloaded(from: url, completion: completion)
}

private func setupContentWith(image: UIImage) {
    yourImageView?.image = image
}

最后,当您没有图像时,您可以 return 一些您认为合适的默认高度。如果你有图像,你 return 它的高度。

func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
    if images.count > indexPath.row {
        // We have the image, return it's height
        return images[indexPath.row].size.height
    } else {
        // We do not have the image, return some default height
        return 50 // Or some height you find approriate
    }
}