Количество строк для UILabel не обновляется, как ожидалось, при нажатии TableViewCell - PullRequest
0 голосов
/ 30 апреля 2019

Я изменяю атрибут numberOfLines на метке, которая находится в пользовательском UITableViewCell при касании ячейки. Однако это не отражается в пользовательском интерфейсе до второго касания. Ячейка настроена как ячейка прототипа в табличном представлении, чтобы первоначально иметь 2 строки.

Интересно, что когда я печатаю значение numberOfLines до и после запуска моей функции tapped(), значения начинаются по-другому, а затем синхронизируются - после первого нажатия я вижу 2 строки до запуска функции, затем 0 строк после запуска функции. Однако после последующих нажатий я вижу одно и то же значение до и после своей функции, из-за чего создается впечатление, что он ничего не делает, даже если пользовательский интерфейс растягивает и уменьшает ячейку, а значение numberOfLines изменяется в следующий раз. didSelectRowAtIndexPath функция работает.

Я вижу это поведение только с tableView.reloadRows(). Если я сделаю полное обновление с tableView.reloadData(), ячейка соответствующим образом увеличится и рухнет при первом касании. Тем не менее, это выглядит немного тупо и не оживляет так хорошо, как reloadRows().

Реализация TableView

    func tableView(_ tableView: UITableView, 
                       didSelectRowAt indexPath: IndexPath) {
         guard let cell = tableView.cellForRow(at: indexPath) as? ReviewTableViewCell
             else { return }
         let data = tableData[indexPath.row]

         print("old number of lines: \(cell.detailLabel.numberOfLines)")

             //data.isOpen is set to false initially
             cell.tapped(data.isOpen)
         tableData[indexPath.row].isOpen = !data.isOpen
             tableView.reloadRows(at: [indexPath], with: .fade)

             print("old number of lines: \(cell.detailLabel.numberOfLines)")


//      tableView.reloadData()
    }

Метод ячейки пользовательского представления таблицы

    func tapped(_ isOpen: Bool) {
         if !isOpen {
              detailLabel.numberOfLines = 0     }
         else {
          detailLabel.numberOfLines = 2     }
    }

Я ожидаю, что этот код расширит ячейку после ее перезагрузки с помощью tableView.reloadRows(), если numberOfLines установлен на 0, и свернет ячейку, когда она установлена ​​на 2. Это работает, но только после нажатия на ячейку два раза + Это должно работать и с первым касанием.

Вот ссылка на gif, которая показывает проблему: https://imgur.com/a/qe2uAXj

Вот пример проекта, который похож на то, что происходит в моем приложении: https://github.com/imattice/CellLabelExample

Ответы [ 2 ]

1 голос
/ 30 апреля 2019

Просто чтобы прояснить, чтобы этот трюк сработал UILabel обычно должен быть ограничен на каждой стороне своим суперпредставлением, таким образом, когда он меняет свою intrinsicContentSize, он может толкать каждую сторону для размещения текста.
Сказав это, попробуйте обернуть прослушиваемый метод с помощью этих двух методов:

tableView.beginUpdates()
if !isOpen {
    detailLabel.numberOfLines = 0     
}
else {
    detailLabel.numberOfLines = 2     
}
tableView.endUpdates()

Конечно, tableview должен быть установлен на автоматический размер:

tableView.estimatedRowHeight = <#What you want#>
tableView.rowHeight = UITableView.automaticDimension
0 голосов
/ 09 мая 2019

Мне удалось понять, что происходит. Проблема состоит из двух частей.

Первая часть зовет reloadRows(). Этот метод заменяет ячейки на новую, а не обновляет уже существующую. Поэтому я меняю количество строк в этой скрытой ячейке подкачки, а не в отображаемой ячейке. Это поведение упоминается в документах :

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

Кроме того, я использую структуры в качестве модели данных для отслеживания открытого состояния ячейки. В Swift структуры копируются при записи, что означает, что если значение в этой структуре изменяется, создается новая структура, а не изменяется значение той структуры, на которую я указываю. Это означает, что строка tableData[indexPath.row].isOpen = !data.isOpen не делает ничего полезного - мы смотрим на структуру tableData по пути индекса, получаем ее значение isOpen, копируем новую структуру и изменяем значение isOpen этой новой структуры, а затем выкидываем ее потому что новая структура нигде не назначена.

Решение состоит в том, чтобы не использовать метод reloadRows() и использовать А) class для объекта данных B) заменить данные в indexPath.row на скопированную структуру

    func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
        guard let cell = tableView.cellForRow(at: indexPath) as? CustomCell else { return }
        var data = tableData[indexPath.row]

        tableView.beginUpdates()
        cell.tapped(isOpen: data.isOpen)
        data.isOpen = !data.isOpen

        tableData[indexPath.row] = data
        tableView.endUpdates()
    }
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...