[swift] ContainerView 에 대하여

Clint Jang
6 min readSep 23, 2018

--

iOS에서 ContainerView를 사용하면 View 가 하위 View 를 가질 수 있으며

하위 View 는 자체 View Controller로 관리됩니다.

기본적으로 iOS에서 사용할 수있는 UINavigationController 및 UITabBarController와 같은 UIViewController가 이 범주에 속합니다.

아래는 Container View를 사용하는 방법을 설명하는 간단한 프로젝트를 생성 하였고, 위임을 사용하여 부모 뷰 컨트롤러와 자식 뷰 컨트롤러 사이의 통신을 가능하게하는 방법을 설명한 Sample 링크 입니다.

항상 소스를 실행해 보는 것이 제일 이해하기 쉬운 방법인 것 같습니다.

위에 Sample 소스는 스토리보드와 코드만을 이용한 방법을 설명합니다.

1. 스토리 보드를 이용하는 것을 보여준 셈플

  • 스크롤 뷰에 Container View 를 넣어본 셈플

그리고

2. 코드 레벨만으로 추가했다 제거

add Child Controller 버튼을 눌렀을 때..

코드 레벨로 버튼을 눌렀을 때 추가하고 제거하는 셈플 소스를 넣어두었습니다.

Apple 문서에서는 Implementing a Container View Controller 부분에 설명이 되어있네요.

  • 단순하게 addSubView를 하면 부모자식관계는 성립하지 않습니다.
  • addChildViewController를 이용해서 자식 컨트롤러를 추가합니다.
  • 추가 완료된 이후에는 부모컨트롤러에서 didMove:를 호출해 줘야 합니다.
  • removeFromParentViewController를 이용해서 자식 컨트롤러를 제거합니다.
  • 제거 순서는 자식의 부모 뷰를 Container View 계층에서 제거한 후, 자식과 부모는 Container View Controller와 연결을 끊어야 합니다.
  • 자식 컨트롤러가 오토레이아웃 환경인 경우 translatesAutoresizingMaskIntoConstraints 설정도 신경씁니다.

코드로 AddViewController를 호출 한 부분

// addChildController
@IBAction func onAddChildController(_ sender: Any) {
let storyboard = UIStoryboard(name: "Other", bundle: nil)
let addViewController = storyboard.instantiateViewController(withIdentifier: "AddViewController")
// if Constraints
// addViewController.view.translatesAutoresizingMaskIntoConstraints = false

self.addChildViewController(addViewController)
self.view.addSubview(addViewController.view)

// if Constraints
// self.view.addConstraints(addViewController.view.constraints)

addViewController.didMove(toParentViewController: self)
}

코드 부분으로 추가한 AddViewController의 내부 소스 부분

import UIKit

class AddViewController: UIViewController {

deinit {
// check remove self
print(#function)
}

override func viewDidLoad() {
super.viewDidLoad()

// TEST backgroundColor
view.backgroundColor = #colorLiteral(red: 0.9098039269, green: 0.4784313738, blue: 0.6431372762, alpha: 1)
}

// willMove -> It appears on the parent screen.
override func willMove(toParentViewController parent: UIViewController?) {
print(#function)
if let `parent` = parent as UIViewController? {
print(parent)
}
}

// It appears on the parent screen. -> didMove
override func didMove(toParentViewController parent: UIViewController?) {
print(#function)
if let `parent` = parent as UIViewController? {
print(parent)
}
}

// remove child view controller
@IBAction func onRemoveChildViewController(_ sender: Any) {
// Notify the parent to remove it by calling willMove.
// willMove 를 호출해서 제거한다는 것을 알립니다.
self.willMove(toParentViewController: nil)
// Remove Constraint.
// 제약사항 제거
self.view.removeFromSuperview()
// Remove the relationship of the child connected to the parent.
// 부모에 연결된 자식의 관계를 제거합니다.
self.removeFromParentViewController()
}
}

읽어주셔서 감사합니다.

즐거운 하루 되세요 :) 🙇‍

--

--