UITableViewCell изображение не полная ширина - PullRequest
0 голосов
/ 31 марта 2020

Я пытаюсь заполнить UITableView изображениями, которые растягиваются на полную ширину и автоматически устанавливают свои высоты. Я попытался установить estimatedHeightForRowAtIndexPath и heightForRowAt на UITableView.automaticDimension, но они кажутся очень маленькими.

У моего CustomTableViewCell есть UIImage с ограничениями, установленными на 0 со всех сторон.

Я начинаю думать, что это может быть связано с тем, что main.storyboard является Viewcontroller, содержащим UITableView, источник данных и делегат которого установлены для контроллера представления. Должен ли main.storyboard быть UITableViewController?

Может кто-нибудь сказать мне, что я делаю неправильно?

Вот как это выглядит в настоящее время:

simulator uitableview custom cells small images

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
    }
}

РЕДАКТИРОВАТЬ : вот то, на что это похоже, когда режим содержания изображения установлен на Aspect Fill.

aspect fill

Я также только что заметил предупреждение:

[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.

1 Ответ

0 голосов
/ 31 марта 2020

Проблема в том, что вы не можете обновить высоту ячейки после того, как она была создана и нарисована на экране. Но что вы можете сделать, так это то, что когда вы загружаете изображение, вы уведомляете TableView о перезагрузке указанной строки c, к которой принадлежит изображение. Это назовет heightForRowAtIndexPath, но теперь вы будете знать точную высоту изображения.

Определите массив, в котором вы будете хранить извлеченные изображения в вашем ViewController.

private var images: [UIImage] = []

Теперь при создании ячейки вы либо передаете это изображение в ячейку, либо запускаете задачу загрузки с обратным вызовом, который уведомит TableView о перезагрузке указанной строки c.

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
}

И, наконец, когда у вас нет изображения, вы можете вернуть некоторую высоту по умолчанию, которую вы считаете подходящей. И если у вас есть изображение, вы возвращаете его высоту.

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
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...