Можно ли изменить содержимое UIStackView в рантайме
Что проверяют
Знаете ли вы разницу между arrangedSubviews и subviews и умеете ли менять стек без визуальных артефактов. Следом обычно просят показать анимацию скрытия элемента или спрашивают, почему для длинного списка стек не подходит.
Как отвечать
Да, содержимое и настройки стека меняются в любой момент, раскладку он пересчитывает сам через Auto Layout:
addArrangedSubview(_:)иinsertArrangedSubview(_:at:): добавляют вью в конец или на нужную позицию, заодно она становится сабвью стека;removeArrangedSubview(_:): убирает вью только из управляемого списка. Из иерархии она не уходит и остаётся висеть поверх стека со старым фреймом, поэтому следом нуженremoveFromSuperview(). Хватит и одногоremoveFromSuperview(): он удаляет вью из обоих списков;isHidden: скрытая вью не занимает места, стек схлопывает промежуток. Это самый дешёвый способ показывать и прятать блоки без пересоздания;- свойства самого стека:
axis,spacing,alignment,distribution,setCustomSpacing(_:after:), а такжеlayoutMarginsвместе сisLayoutMarginsRelativeArrangementтоже меняются на лету.
Анимация делается так: меняете isHidden или alpha внутри UIView.animate, а если стек вложен в другой лэйаут, там же вызываете layoutIfNeeded() у общего родителя. Стоит упомянуть, что с iOS 14 стек рендерится сам и у него работает backgroundColor, раньше для фона подкладывали отдельную вью.
Где спотыкаются
Вызывают только removeArrangedSubview и потом ищут, откуда в углу экрана взялся «призрак». Утечки памяти тут нет, как часто говорят: вью просто удерживается родителем и остаётся на экране.
Присваивают isHidden = true уже скрытой вью внутри анимационного блока. На ряде версий iOS это рассинхронизирует внутреннее состояние, и элемент потом не показывается. Перед присваиванием сравнивайте с текущим значением.
Строят ленту на сотни элементов из стека внутри UIScrollView. Стек создаёт и держит все вью сразу, переиспользования нет, для такого случая нужен UICollectionView или UITableView.