View Controller 생명주기
View 의 상태

뷰가 보여지는 상황은 크게 4가지로 구분
- Appearing : View가 화면에 나타나는 중
- Appeard : View가 화면에 완전히 나타난 상태
- Disappearing : View가 화면에서 사라지는 중
- Disappeared : View가 화면에서 완전히 사라진 상태
View의 Lifecycle

- viewDidload()
override func viewDidLoad(){
super.viewDidLoad()
}
- ViewController의 모든 View가 메모리에 로드됐을 때 호출
(인스턴스의 생성과 준비 그리고 Outlet 설정이 끝나면 호출)
(Load라는건 Outlet을 불러온다는 의미)
- 메모리에 처음 로드될 때 한 번만 호출
- 보통 딱 한 번만 호출될 행위들을 이 메서드에 정의
- 초기화 코드를 넣기에 좋음(ex.. init())
- View와 관련된 추가적인 작업, 네트워크 호출
- 복잡한 연산이나 집약적 네트워크 같은 복잡한 작업을 하지 않는다.
- UI 업데이트하기 좋음
- viewDidload()에서 주의해야할 건 geometry(기하)
-> view의 geometry는 스토리보드에서 여전히 정사각형 형태 그래서 viewDidload에서 geometry와 관련된 계산을 하는건 쓸모없음
- viewWillAppear()
override func viewWillAppear(_ animated: Bool){
super.viewWillAppear(animated)
}
- View가 View 계층에 추가되고, 화면에 보이기 직전에 매번 호출
(이게 호출되면 화면에 나올거라는걸 확신할 수 있음)
- 다른 View로 이동했다가 돌아올 때 호출
- View와 관련된 추가적인 초기화 작업
- 복잡한 작업을 시작하기 좋음
- 복잡한 작업을 다른 thread에서 하게 하는데 활용할 수 있음
- viewDidAppear()
override func viewDidAppear(_ animated: Bool){
super.viewDidAppear(animated)
}
- ViewController의 View가 View계층에 완전히 추가된 후 호출
(화면이 나타난 직후 호출되는 메소드)
- View를 나타낼 때 필요한 추가 작업
- 애니메이션을 시작하는 작업
- viewWillDisappear()
override func viewWillDisappear(_ animated: Bool){
super.viewWillDisappear(animated)
}
- ViewController의 View가 View계층에서 사라지기 전에 호출
- View가 생성된 뒤 작업한 내용을 되돌리는 작업
(보통 viewDidAppear()에서 했던 것을 undo(되돌리기)하게 됨)
- 최종적으로 데이터를 저장하는 작업
- 여기에서 애니메이션을 멈추거나 Gyro(회전이나 평형상태 측정)을 보는걸 멈춤(곧 화면이 사라질 거니까)
- viewDidDisappear()
override func viewDidDisappear(_ animated: Bool){
super.viewDidDisappear(animated)
}
- ViewController의 View가 View계층에서 완전히 사라진 뒤 호출
- View가 사라지는 것과 관련된 추가 작업
- viewWillAppear()안에서 네트워크로부터 가져온 데이터를 풀어줄 수 있음
특별한 생명주기
Layout subviews관련 메서드
UIView의 Layout이란, 화면에서 UIView의 크기와 위치를 의미
View와 ViewController의 레이아웃 사이클

- update(step 1) : Autolayout의 제약(Constraints)을 갱신. 제약의 갱신은 subview로부터 superview의 순서로 호출 됨
- layout(step 2) : step1의 제약을 바탕으로 레이아웃을 실행. 여기에서 view의 center와 bounds를 결정. 레이아웃의 갱신은 superview로부터 subview의 순서로 호출 됨.
- draw(step 3) : step2의 레이아웃 후에 UIView의 drawRect(rect:CGRect)가 호출 됨. 이그리기 단계에서는 CoreGraphics를 사용하여 그리게 됨
레이아웃 사이클은 제약, 레이아웃, 그리기의 순으로 진행되고, 스텝 1,2는 UIView와 UIViewController 양쪽에 메소드가 내장되어 있음.
ViewController에서 레이아웃이 결정되는 과정
1. viewWillLayoutSubviews() 메서드 호출
2. ViewController의 컨텐트 뷰가 layoutSubviews()메서드 호출
layoutSubviews() : 현재 레이아웃 정보들을 바탕으로 새로운 레이아웃 정보를 계산
이후 뷰 계층구조를 순회하면서 모든 하위 뷰들이 동일한 메서드를 호출
3. 레이아웃 정보의 변경사항을 뷰들에게 반영
4. viewDidLayoutSubviews()메서드 호출
요약 : viewWillLayoutSubviews()호출 -> layoutSubviews()호출 -> viewDidLayoutSubviews()호출
-
viewWillLayoutSubviews()
- 뷰의 bounds가 변하면 뷰는 하위 뷰(subView)들의 위치를 조정하게 됨
- ViewWillLayoutSubViews는 뷰의 bounds가 변해서, 뷰가 서브뷰의 배치를 조정하기 직전임을 뷰 컨트롤러에게 알림
- 뷰가 자신의 서브뷰들의 배치를 조정하기 전에 하고 싶은게 있다면 viewWillLayoutSubViews를 override
- 다음과 같은 작업을 수행하고자 할 때 이 매서드를 override하여 사용
뷰들을 추가하거나 제거
뷰들의 크기나 위치를 업데이트
레이아웃 constraint를 업데이트
뷰와 관련된 기타 프로퍼티들을 업데이트
-
layoutSubviews()
- 뷰의 크기가 변경될 때마다 이에 대응하여 하위 뷰들의 크기&위치가 변경되어야 함
auto layout을 사용하면 각 뷰의 autoresizingMask프로퍼티를 설정하여 상위 뷰의 크기가 변경되었을 때 어떻게 대응할지 규칙을 정할 수 있음.
- 뷰의 크기가 변경될 발생하면 우선 하위 뷰들의 autoresizing 동작을 적용하는데, 변경사항을 반영하기 위하여 layoutSubviews()메서드를 호출
(이 메서드 역시 하위 뷰들에서도 연쇄적으로 호출 됨)
- viewDidLayoutSubviews()
- 레이아웃이 결정되고 나서 아래와 같은 일을 수행하고자 할 때 이 메서드를 override하여 사용
다른뷰들의 컨텐트 업데이트
뷰들의 크기나 위치를 최정적으로 조정
테이블의 데이터를 reload
+ Geometry를 위한 특별한 생명주기
viewWillLayoutSubviews(), viewDidLayoutSubviews()사이에서 모든 Autolayout이 동작(Constraints를 기초로 하는 것들)
- Geometry 처리를 할 수 있는 유일한 곳
- bound가 바뀌지 않는다고해도 반복적으로 호출
-
viewWillTransitionToSize() : 컨테이너에 뷰의 크기가 변경될 것임을 알림.
-
didReceiveMemoryWarning : 메모리가 부족할 때 호출
-
awakeFromNib : 매우 초반에 호출됨(준비하기 전, Outlet 설정하기전, 그런 모든 것들 이전에 호출). 오직 스토리보드로부터 나오는 경우에만 해당. 스토리보드에서 나오는 모든 오브젝트에 보내지는 메소드. 많이 사용하지 않았으면 함(대신 viewDidLoad나 viewWillAppear 사용). 굉장히 이례적인 상황에 사용(정말 이른시기에 뭔가를 해야할 때, 다른 오브젝트의 Controller로 자기 자신을 설정해야 하는 경우)
-
보통 스토리보드로부터 인스턴스화 됨 -> awakeFromNib() -> 어딘가로 segue(세그웨이) 연결되어 있으면 segue 준비 -> Outlet 설정 -> viewDidLoad() -> viewWillAppear() -> viewDidAppear() -> viewWillDisappear() -> viewDidDisappear() -> viewDidUnload()
(화면이 켜져있든 꺼져있든 항상 viewWillLayoutSubview()와 viewDidLayoutSubview()을 설정할 수 있음 여기서 geometry변화에 반응하게 됨, constraint이 아닌 다른 설정을 할 때 필요) (언제든 메모리가 부족해질 땐 didReceiveMemoryWarning() 호출)
참조
Zedd0202
Hoojeong
김킥킥
김종권의 iOS앱 개발 알아가기