„Widok kontenera” scenorysu to tylko standardowy UIView
obiekt. Nie ma specjalnego typu „widoku kontenera”. W rzeczywistości, jeśli spojrzysz na hierarchię widoków, zobaczysz, że „widok kontenera” jest standardem UIView
:
Aby osiągnąć to programowo, stosujesz „ograniczenie kontrolera widoku”:
- Utwórz wystąpienie kontrolera widoku podrzędnego, wywołując
instantiateViewController(withIdentifier:)
obiekt serii ujęć.
- Zadzwoń
addChild
do kontrolera widoku rodzica.
- Dodaj kontroler widoku
view
do hierarchii widoku za pomocą addSubview
(a także ustaw odpowiednio frame
ograniczenia lub).
- Wywołaj
didMove(toParent:)
metodę na podrzędnym kontrolerze widoku, przekazując odwołanie do nadrzędnego kontrolera widoku.
Zobacz implementowanie kontrolera widoku kontenera w Przewodniku programowania kontrolera widoku i sekcji „Implementowanie kontrolera widoku kontenera” w odwołaniu do klasy UIViewController .
Na przykład w Swift 4.2 może wyglądać tak:
override func viewDidLoad() {
super.viewDidLoad()
let controller = storyboard!.instantiateViewController(withIdentifier: "Second")
addChild(controller)
controller.view.translatesAutoresizingMaskIntoConstraints = false
view.addSubview(controller.view)
NSLayoutConstraint.activate([
controller.view.leadingAnchor.constraint(equalTo: view.leadingAnchor, constant: 10),
controller.view.trailingAnchor.constraint(equalTo: view.trailingAnchor, constant: -10),
controller.view.topAnchor.constraint(equalTo: view.topAnchor, constant: 10),
controller.view.bottomAnchor.constraint(equalTo: view.bottomAnchor, constant: -10)
])
controller.didMove(toParent: self)
}
Uwaga, powyższe w rzeczywistości nie dodaje „widoku kontenera” do hierarchii. Jeśli chcesz to zrobić, zrób coś takiego:
override func viewDidLoad() {
super.viewDidLoad()
// add container
let containerView = UIView()
containerView.translatesAutoresizingMaskIntoConstraints = false
view.addSubview(containerView)
NSLayoutConstraint.activate([
containerView.leadingAnchor.constraint(equalTo: view.leadingAnchor, constant: 10),
containerView.trailingAnchor.constraint(equalTo: view.trailingAnchor, constant: -10),
containerView.topAnchor.constraint(equalTo: view.topAnchor, constant: 10),
containerView.bottomAnchor.constraint(equalTo: view.bottomAnchor, constant: -10),
])
// add child view controller view to container
let controller = storyboard!.instantiateViewController(withIdentifier: "Second")
addChild(controller)
controller.view.translatesAutoresizingMaskIntoConstraints = false
containerView.addSubview(controller.view)
NSLayoutConstraint.activate([
controller.view.leadingAnchor.constraint(equalTo: containerView.leadingAnchor),
controller.view.trailingAnchor.constraint(equalTo: containerView.trailingAnchor),
controller.view.topAnchor.constraint(equalTo: containerView.topAnchor),
controller.view.bottomAnchor.constraint(equalTo: containerView.bottomAnchor)
])
controller.didMove(toParent: self)
}
Ten ostatni wzorzec jest niezwykle przydatny, jeśli kiedykolwiek przechodzisz między różnymi kontrolerami widoku podrzędnego i chcesz się tylko upewnić, że widok jednego dziecka znajduje się w tej samej lokalizacji i widoku poprzedniego dziecka (tj. Wszystkie unikalne ograniczenia dla miejsca docelowego są podyktowane przez widok kontenera, zamiast za każdym razem przebudowywać te ograniczenia). Ale jeśli wykonujesz tylko proste zawarcie widoku, potrzeba tego oddzielnego widoku kontenera jest mniej przekonująca.
W powyższych przykładach zamierzam translatesAutosizingMaskIntoConstraints
samodzielnie false
zdefiniować ograniczenia. Oczywiście możesz pozostawić translatesAutosizingMaskIntoConstraints
jako true
i ustawić zarówno widok, jak frame
i autosizingMask
dla dodawanych widoków, jeśli wolisz.
Zobacz poprzednie wersje tej odpowiedzi dla wersji Swift 3 i Swift 2 .