Ваш код вызывает сбой из-за этой строки
let cell = tableView.cellForRow(at: indexPath) as! AvailableRideCell
С Документация Apple мы знаем, что этот метод используется для оптимизации.Вся идея состоит в том, чтобы получить высоту клеток, не тратя время на создание самих клеток.Таким образом, этот метод вызывается перед инициализацией любой ячейки, а tableView.cellForRow(at: indexPath)
возвращает nil
.Потому что ячеек еще нет.Но вы делаете принудительное развертывание с помощью as! AvailableRideCell
, и ваш код падает.
Итак, сначала вам нужно понять , почему вы не должны использовать какие-либо ячейки внутри метода cellForRow(at )
,После этого вам нужно изменить логику, чтобы можно было вычислять высоту содержимого без вызова ячейки.
Например, в своих проектах я использовал это решение
Строковая реализация
extension String {
func height(for width: CGFloat, font: UIFont) -> CGFloat {
let maxSize = CGSize(width: width, height: CGFloat.greatestFiniteMagnitude)
let actualSize = self.boundingRect(with: maxSize,
options: [.usesLineFragmentOrigin],
attributes: [NSAttributedStringKey.font: font],
context: nil)
return actualSize.height
}
}
Реализация UILabel
extension String {
func height(for width: CGFloat, font: UIFont) -> CGFloat {
let labelFrame = CGRect(x: 0, y: 0, width: width, height: CGFloat.greatestFiniteMagnitude)
let label = UILabel(frame: labelFrame)
label.numberOfLines = 0
label.lineBreakMode = .byWordWrapping
label.font = font
label.text = self
label.sizeToFit()
return label.frame.height
}
}
При этом все, что вам нужно, это вычислить вашу метку и сохранить ее шрифт.
var titles = ["dog", "cat", "cow"]
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
// number of rows is equal to the count of elements in array
return titles.count
}
func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
let cellTitle = titles[indexPath.row]
return cellTitle.height(forWidth: labelWidth, font: labelFont)
}
Динамическое изменение высоты строк
Если вам нужно обновить высоту строки, все, что вам нужно сделать, это вызвать этот метод, когда ваш контент был изменен.indexPath
- индексный путь измененного элемента.
tableView.reloadRows(at: [indexPath], with: .automatic)
Надеюсь, он вам поможет.