Представление контейнера можно легко добавить в раскадровку с помощью редактора интерфейса. При добавлении представление контейнера имеет представление заполнителя, переход для встраивания и (дочерний) контроллер представления.
Однако я не могу найти способ программно добавить представление контейнера. На самом деле я даже не могу найти класс с таким именем UIContainerView
.
Название класса Container View, несомненно, станет хорошим началом. Будем очень признательны за полное руководство, включая переход.
Мне известно о руководстве по программированию контроллера представления, но я не считаю его таким же, как интерфейс Builder для средства просмотра контейнеров. Например, если ограничения установлены правильно, (дочернее) представление адаптируется к изменениям размера в представлении контейнера.
источник
ViewController
жизненный цикл встроенного .ViewController
Жизненный цикл встроенного с помощью Interface Builder нормальный, но тот, который добавлен программноviewDidAppear
, не имеет ни,viewWillAppear(_:)
ниviewWillDisappear
.viewWillAppear
иviewWillDisappear
вызываются на дочернем контроллере представления, нормально. Если у вас есть пример, в котором их нет, вы должны уточнить или опубликовать свой вопрос, спрашивая, почему это не так.Ответы:
«Контейнерное представление» раскадровки - это просто стандартный
UIView
объект. Специального типа "контейнерный вид" нет. Фактически, если вы посмотрите на иерархию представлений, вы увидите, что «контейнерное представление» является стандартомUIView
:Чтобы достичь этого программно, вы используете «сдерживание контроллера представления»:
instantiateViewController(withIdentifier:)
объект раскадровки.addChild
свой родительский контроллер представления.view
в иерархию представления с помощьюaddSubview
(а также установите соответствующиеframe
ограничения или).didMove(toParent:)
метод на контроллере дочернего представления, передав ссылку на контроллер родительского представления.См. Раздел « Реализация контроллера представления контейнера» в Руководстве по программированию контроллера представления. и раздел «Реализация контроллера представления контейнера» справочника по классам UIViewController .
Например, в Swift 4.2 это может выглядеть так:
Обратите внимание, что приведенное выше на самом деле не добавляет к иерархии «представление контейнера». Если вы хотите это сделать, сделайте что-то вроде:
Этот последний шаблон чрезвычайно полезен при переходе между различными контроллерами дочерних представлений, и вы просто хотите убедиться, что одно дочернее представление находится в том же месте, что и предыдущее дочернее представление (т.е. все уникальные ограничения для размещения продиктованы представлением контейнера, вместо того, чтобы каждый раз перестраивать эти ограничения). Но если просто выполнить простое включение представления, потребность в этом отдельном представлении контейнера будет менее острой.
В приведенных выше примерах, я устанавливаю
translatesAutosizingMaskIntoConstraints
дляfalse
определения ограничений себя. Вы, очевидно, можете оставитьtranslatesAutosizingMaskIntoConstraints
какtrue
и установить иframe
иautosizingMask
для добавляемых вами представлений, если хотите.См. Предыдущие версии этого ответа для представлений Swift 3 и Swift 2 .
источник
ViewController
жизненный цикл встроенного .ViewController
Жизненный цикл встроенного с помощью Interface Builder нормальный, но тот, который добавлен программноviewDidAppear
, не имеет ни,viewWillAppear(_:)
ниviewWillDisappear
.ViewController
«ыviewDidAppear
называется в его родителяviewDidLoad
, вместо того , чтобы во время своего родителяviewDidAppear
viewDidAppear
, [но] ниviewWillAppear(_:)
илиviewWillDisappear
». Вwill
обоих сценариях методы появления вызываются правильно. При этом нужно звонитьdidMove(toParentViewController:_)
программно, иначе они этого не сделают. По поводу сроков появления. методы, они вызываются в одинаковой последовательности в обоих направлениях. Что отличает, тем не менее, так это времяviewDidLoad
, потому что при встраивании он загружается раньшеparent.viewDidLoad
, а при программной, как мы и ожидали, это происходит во времяparent.viewLoadLoad
.translatesAutoresizingMaskIntoConstraints = false
. Я не знаю, зачем это нужно или почему это помогает, но спасибо, что включили это в свой ответ.@ Ответ Роба в Swift 3:
источник
подробности
Решение
использование
Полный образец
Полученные результаты
источник
tableViewController
вviewController
но не могу установить заголовок первых. Не знаю, возможно ли это. Я разместил этот вопрос . Как хорошо с вашей стороны, если вы посмотрите на это.Вот мой код в Swift 5.
}
использование
Используйте другую функцию встраивания с контроллером представления без раскадровки.
источник
removeFromParent
предотвращает ваш вызов, как бы вы изменили свой класс, чтобы это разрешить?