Проблемы с компоновкой UIStackView при изменении класса размера в UITableViewCell

У меня возникают проблемы с компоновкой с моим горизонтальным UIStackView в пользовательском UITableViewCell при отображении / скрытии arrangedSubviews когда изменяется horizontalSizeClass .

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

Вопросы:

  • Иногда соответствующие подсмотры либо не показаны, либо не скрыты, когда они должны быть.
  • Иногда подвыборы некорректно выкладываются, не заполняя ширину представления стека.

Попытки:

Я попытался выполнить несколько действий для макета:

  • Переопределение viewWillTransitionToSize:transitionCoordinator для перезагрузки таблицы и / или viewWillTransitionToSize:transitionCoordinator
  • Переопределение viewWillTransitionToTraitCollection:withTransitionCoordinator для перезагрузки таблицы и / или viewWillTransitionToTraitCollection:withTransitionCoordinator
  • Переопределение layoutSubviews для повторной настройки расположения представлений стека.
  • Вызов [self setNeedsLayout] , [self layoutIfNeeded] после настройки ячейки
  • Принудительная компоновка в других местах
  • Изменение приоритетов ограничения макета subview до 999
  • Ограничение UILabel s до 1 строки и установка preferredMaxLayoutWidth
  • Настройка contentHuggingPriority и contentHuggingPriority на представлениях
  • Использование статического значения для rowHeight вместо UITableViewAutomaticDimension
  • И т.п.

Похоже, что проблемы не устранены.

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


Пример проекта

Я создал образец проекта, чтобы проиллюстрировать проблемы макета. На данный момент я не уверен, что UIStackView ошибочно, или если я неправильно его использую.

Пример проекта: https://github.com/bradgmueller/StackViewTest

В примере проекта используется пользовательский UITableViewCell с представлениями, настроенными в xib. Строковые объекты генерируются с различными конфигурациями для иллюстрации динамических макетов, которые должна принимать ячейка:

  • Отступы / без отступов
  • Отображение разделителя или нет
  • Отображение / скрытие кнопки «как»
  • Отображение / скрытие кнопки «Поделиться»
  • Отображение / скрытие кнопки «Информация», где существует одна информационная кнопка для UIUserInterfaceSizeClassCompact а другая для UIUserInterfaceSizeClassRegular

Текстовая метка существует с текстом, указывающим, какое из представлений должно отображаться, чтобы иллюстрировать, когда представления ненадлежащим образом отображаются / скрыты. Кроме того, за UIStackView существует красный фон, чтобы проиллюстрировать, когда представление стека не UIStackView ширину.

Скриншоты:

Первоначальный макет – никаких проблем Первоначальный макет - никаких проблем

После поворота – проблемы, отмеченные красным «X», Вращение - возникают проблемы


Я был бы признателен за понимание, спасибо заранее!

Как правило, представления стека довольно хорошие, но когда они становятся более сложными и управляют большим количеством просмотров, они кажутся менее надежными.

Я обнаружил, что лучший способ избежать проблем с макетом – сделать одну или две вещи:

  1. Используйте несколько представлений стека . Вместо того, чтобы группировать все мои представления в одно представление стека, наличие нескольких меньших представлений стека кажется более надежным, поскольку каждый из них управляет меньшим количеством просмотров.
  2. Удалите / повторно вставьте виды, а не скройте их . Хотя представления стека должны рассматривать «скрытые» представления, как если бы они были удалены из иерархии, я получил намного лучшие результаты макета, когда я фактически удалил их из иерархии.

Пример:

Более надежные результаты макета:

 if (hideSubview == YES) { [subview removeFromSuperview]; } else { [stackView insertArrangedSubview:subview atIndex:0]; } 

Не так надежно:

 subview.hidden = hideSubview;