#ios #swift #uitableview #textview #swift5
#iOS #swift #uitableview #textview #swift5
Вопрос:
В моем ViewController есть TableView, и каждая ячейка в TableView имеет TextView, в котором отображаются стихи. Некоторые стихи длинные, а некоторые короткие. Я сделал некоторый код для расширения UITableViewCell при нажатии, чтобы пользователь мог сосредоточиться на чтении только одного стихотворения, а остальные были бы скрыты.
Это мой код:
@IBOutlet weak var poemasTableView: UITableView!
var selectedRowIndex = -1
func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
if indexPath.row == selectedRowIndex {
return 240 //Expanded
}
return 55 //Not expanded
}
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
if selectedRowIndex == indexPath.row {
selectedRowIndex = -1
} else {
selectedRowIndex = indexPath.row
}
tableView.reloadRows(at: [indexPath], with: .automatic)
}
Это работает нормально, однако я хочу сделать что-то еще. При нажатии на ячейку я хочу, чтобы она расширялась, чтобы соответствовать содержимому TextView. Так, например, если стихотворение слишком велико, новая высота должна быть 320, но если она короче, она должна быть 150 и так далее.
Как я мог это сделать?
Комментарии:
1. Во-первых, есть ли причина, по которой вы используете
UITextView
вместоUILabel
? Во-вторых, вы пробовали поиск? Здесь есть много похожих вопросов и ответов, а также много-много примеров в Интернете.
Ответ №1:
Вы можете рассчитать ограничительную рамку всего стихотворения, используя boundingRectWithSize
. А затем вы бы присвоили вычисленную высоту высоте строки.
func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
if indexPath.row == selectedRowIndex {
// Expanded
let poem: String = poems[indexPath.row]
let size = CGSize(width: poemasTableView.frame.width, height: .greatestFiniteMagnitude)
let rectangle: CGRect = NSString(string: poem).boundingRect(with: size,
options: .usesLineFragmentOrigin,
attributes: [.font: UIFont.systemFont(ofSize: 16)],
context: nil)
let maximum_height: CGFloat = 1366
let rowHeight: CGFloat = min(rectangle.height, maximum_height)
return rowHeight
}
return 55 //Not expanded
}
Комментарии:
1. Спасибо за ваш ответ, однако у меня все еще есть проблема. Поскольку я использую firebase и CoreData в своем приложении, вместо poems я бы использовал «arrayPoemas», который имеет тип «Poemas», а не тип String. Таким образом, в строке «let poem: String» появляется ошибка, поскольку она не может преобразовать тип «Poemas» в тип String. И если я сотру эту «:String», это не позволит мне использовать инициализатор «NSString ()». Как я мог это исправить?
2. Я не очень хорошо знаком с Core Data, но я думаю, что это было бы так
let poem: String = (arrayPoemas[indexPath.row].value(forKeyPath: "text") as? String) ?? ""
, поскольку суммированиеtext
— это поле вашего объекта Poem, которое содержит текст стихотворения.3. Я пытался использовать код, но есть проблема. Я не знаю, почему, когда я нажимаю UITableViewCell, он расширяет их все до определенной высоты (я думаю, 320), а не до высоты содержимого.
4. Из вашего вопроса я понял, что вам нужна максимальная высота, на случай, если стихотворение действительно длинное. 320 на самом деле несколько маловат, поэтому я обновил код, чтобы указать максимальную высоту 1366. Дайте мне знать, если это сработает.