Просмотр не обновляется после изменения автоматических ограничений компоновки

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

У меня есть ViewController, который содержит UITableView. Высота этого tableView может варьироваться от 0 (не отображается) до того количества, которое оно имеет. Высота вычисляется в ViewController viewDidLoad() путем умножения текущего количества строк на высоту строки.

Первое, что я пробовал, это создать @IBOutlet weak var tableHeightConstraint: NSLayoutConstraint!, связанный с ограничением высоты, установленным в раскадровке. Он имеет только некоторую случайную начальную высоту, но обновляется до правильного значения в ViewController viewDidLoad(), за которым следует метод, который обновляет представление при необходимости:

tableHeightConstraint = NSLayoutConstraint(item: tableView, attribute: NSLayoutAttribute.Height, relatedBy: NSLayoutRelation.Equal, toItem: nil, attribute: NSLayoutAttribute.NotAnAttribute, multiplier: 0, constant: calculatedTableViewHeight)

// At this point I've tried a variety of methods like the following two but actually none has worked for me
view.layoutIfNeeded()

// or
view.updateConstraints()

// or
view.layoutSubviews()

... и даже те же методы на tableView, чтобы быть уверенными, а также положить все это в viewDidLayoutSubviews().

Итак, я попытался сделать следующее, чтобы создать те же ограничения, что и выше, но вместо обновления я просто добавил его в представление: view.addConstraint(tableHeightConstraint). Это действительно имело желаемый визуальный эффект, но в журналах я столкнулся с конфликтом этих двух ограничений высоты, что привело к перерыву исходного. Поскольку моя цель - получить правильный и чистый код, который я продолжал пытаться. Поэтому на этот раз я сначала удалил ограничение из представления, а затем снова добавил отредактированный. Визуально снова все было идеально, но я до сих пор не избавился от противоречивых ограничений.

Итак, мой реальный вопрос (помимо того, что я делал неправильно до сих пор), как я могу - желательно - просто обновить существующее ограничение, за которым следует надлежащее обновление/ретрансляция представления и его подпунктов в любой момент, независимо от того, Я сначала загружаю представление или просто хочу изменить некоторые ограничения, когда пользователь взаимодействует. Большое спасибо за любую помощь!

Ответы

Ответ 1

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

Ваш подход к использованию IBOutlet для ссылки на ограничение, установленное в IB, является хорошим подходом, но вместо назначения нового ограничения этому var вам просто нужно изменить константу ограничения:

tableHeightConstraint.constant = calculatedTableHeight.

Вам не нужно вызывать layoutIfNeeded() здесь, так как ограничения автоматически обрабатывают вызов макета при изменении их констант. updateConstraints() и layoutSubviews() определенно не то, что вы хотите.