Ошибка анимации UITableView - видимая область, вычисленная до анимации - PullRequest
0 голосов
/ 04 июня 2018

У меня есть простой пользовательский интерфейс (очень похожий на Uber), где пользователь может прокручивать табличное представление поверх основного содержимого.

Пользовательский интерфейс и соответствующая ошибка анимации UITableView могут отображаться как:

enter image description here

Вот что происходит:

  • Пользователь нажимает на представление таблицы, и представление таблицы расширяется.Это делается путем добавления ограничения макета, которое гарантирует, что tableView.top = topMenu.bottom.Снятое ограничение - tableView.height = 30.Все выглядит хорошо.
  • Затем пользователь прокручивает определенное количество (более 55 пикселей), и ограничения возвращаются в исходное состояние.Это происходит внутри блока анимации, поэтому поток выглядит плавным.
  • Ошибка возникает здесь.Насколько я понимаю, видимая область tableView рассчитывается по тому, как она будет выглядеть после окончания анимации.Тем не менее, этот расчет происходит до анимации.Поэтому во время анимации в представлении таблицы отображаются только 1-2 ячейки;вызывая ошибку.
  • Я могу обойти эту проблему, временно установив большое значение для высоты tableView и вернув его к небольшому значению только после окончания анимации.Однако это не работает, поскольку безопасная область на iPhoneX покрыта tableView.

Соответствующий код находится здесь:

    private func animateTheChange() {
        UIView.animate(withDuration: 0.8, animations: {
            self.view.setNeedsUpdateConstraints()
            self.view.layoutIfNeeded()
        })
    }

    override func updateViewConstraints() {
        self.touchConstraints()
        super.updateViewConstraints()
    }

    private func touchConstraints() {
        if self.collapsed {
            self.view.addConstraint(self.collapsedConstraint)
            self.view.removeConstraint(self.expandedConstraint)
            if UserHardware.IS_IPHONE_X {
                self.bottomConstraint.constant = 0
            }
        }
        else { //  Expand
            self.view.addConstraint(self.expandedConstraint)
            self.view.removeConstraint(self.collapsedConstraint)
            if UserHardware.IS_IPHONE_X {
                self.bottomConstraint.constant = 34
            }
        }
    }

Соответствующие вопросы Stackoverflow (которые помогают, но нене решить проблему):

1 Ответ

0 голосов
/ 04 июня 2018

Одна опция ...

  • Вставить ваш табличный вид в «содержащий» UIView
  • Ограничить табличный вид сверху и снизу содержащего представления
  • Ограничить содержащий вид снизу до нижней части безопасной области
  • Ограничить содержащий вид сверху до нижней части topMenu с помощью Priority of 250 (низкий уровень по умолчанию) и подключите его к @IBOutlet var tableContainerTop: NSLayoutConstraint!
  • Ограничьте высоту содержащего представления до 30 с помощью Priority of 750 (высокий по умолчанию) и подключите его к @IBOutlet var tableContainerHeight: NSLayoutConstraint!

Когда вы хотите «развернуть» или «свернуть»ваш tableView, измените приоритеты ограничений содержащего представления.

    UIView.animate(withDuration: 0.8, animations: {

        if self.isExpanded {
            self.tableContainerHeight.priority = .defaultHigh
            self.tableContainerTop.priority = .defaultLow
        } else {
            self.tableContainerHeight.priority = .defaultLow
            self.tableContainerTop.priority = .defaultHigh
        }
        self.view.layoutIfNeeded()

    })
...