loadView()에 대한 간단한 고찰
LoadView에 대한 간단한 고찰
Swift Version 5.3
Xcode Version 12.2
ifkakao 2020을 보면서 카카오는 어떻게 일하는 지 어떻게 개발하는 지 많은 눈팅을(ㅎ__ㅎ) 했습니다.
관련 세션을 보다가 눈에 띈 것이 바로 loadView()
입니다.
저는 평소에 뷰 컨트롤러에 화면을 그릴 때 viewDidLoad()
함수를 많이 쓰는데 카카오는 왜 loadView를 쓰는 지 궁금해져서 간단하게 알아보겠습니다.
우선 모를 때는 공식 문서 먼저..
loadView가 뷰를 만드는(create) 메서드고, viewDidLoad가 말 그대로 뷰가 메모리에 로드 되고 난 후에 불리는 메서드니까
loadView가 viewDidLoad 보다는 먼저 호출되나?
1
2
3
4
5
6
7
8
9
10
11
12
|
class ViewController: UIViewController {
override func loadView() {
super.loadView()
print("loadView()")
}
override func viewDidLoad() {
super.viewDidLoad()
print("viewDidLoad()")
}
}
|
cs |
정답!
viewDidLoad나 다른 함수들에서 사용했던 것처럼super.loadView()
를 사용했는데 개발 문서에 아래와 같은 글이 있었습니다..
Your custom implementation of this method should not call super.
왜인지는 모르겠지만.. 일단 하라는 대로 합니다..
super가 아니라 뷰를 직접 만들어주어야 합니다.
1
2
3
4
|
override func loadView() {
self.view = .init() // UIView()
print("loadView()")
}
|
cs |
뷰를 새로 그려서 현재의 뷰 컨트롤러의 루트 뷰에 지정을 해 줍니다.
네, 여기까지는 이해가 된 것 같아요!
그렇다면 인터페이스 빌더로 뷰 컨트롤러를 만들어서도 확인을 해 볼까요?
If you use Interface Builder to create your views and initialize the view controller, you must not override this method.
라고는 하지만...
제가 직접 만들어 본 결과 실행은.. 되더라구요!
must not 이라고 이야기 한 거 보면 crash가 나야할 것 같은데 왜 되는 지 모르게쑴....
그래도 실행은 되니까 알아보자면,
인터페이스 빌더에서 loadView를 사용한다면
1
|
self.view = .init()
|
cs |
이 아니라
1
|
super.loadView()
|
cs |
를 사용해야 합니다.
그래야 인터페이스 빌더에서 그린 화면이 잘 나오기 때문이죠!
뷰를 새로 그려주면 인터페이스 빌더의 내용은 나오지 않게 됩니다.
이렇게 뷰의 배경색을 노란색으로 지정해 놓고 self.view = .init()
을 사용해서 실행을 하게 되면
네 아무런 소식이 없습니다..
그렇다면 super.loadView()
로 바꾸면 어떻게 될까요?
오! 잘 나오네요!
하나만 더 테스트를 해 보겠습니다.
인터페이스 빌더에서 그린 뷰와 클래스 파일에서 그린 뷰 중 어느 것이 나중에 그려질까요?
이렇게 인터페이스 빌더 위에 뷰를 하나 올려놓고,
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
|
public class ViewController: UIViewController {
public override func loadView() {
super.loadView()
let greenView = UIView()
greenView.backgroundColor = .green
self.view.addSubview(greenView)
greenView.translatesAutoresizingMaskIntoConstraints = false
greenView.topAnchor.constraint(equalTo: self.view.topAnchor, constant: 50).isActive = true
greenView.leftAnchor.constraint(equalTo: self.view.leftAnchor, constant: 50).isActive = true
greenView.widthAnchor.constraint(equalToConstant: 100).isActive = true
greenView.heightAnchor.constraint(equalToConstant: 100).isActive = true
}
public override func viewDidLoad() {
super.viewDidLoad()
}
}
|
cs |
이렇게 초록색 뷰를 하나 그려서 실행해보겠습니다!
네! 인터페이스에서 그린 뷰 위에 새로운 뷰가 나오는 것을 볼 수 있습니다.
공식 문서에서
If the view controller has an associated nib file, this method loads the view from the nib file.
라고 했으니 super.loadView()
를 통해서 인터페이스의 뷰를 그리고 그 이후에 해당 메서드가 실행되어서 그런 것 같습니다!
근데 공식 문서에서 쓰지 말라고 하니까 일단 안 쓰는 걸로.....ㅎㅎㅎㅎ
결론
1. loadView()는 뷰 컨트롤러에서 루트 뷰를 그리는 메서드이고, viewDidLoad() 보다도 더 먼저 실행된다.
2. loadView()에서는 뷰를 직접! 초기화 해주어야 한다.
3. loadView()는 코드로 직접 뷰 컨트롤러를 그리는 경우에만 사용해야 한다.
혹시
1. 왜 뷰 컨트롤러를 코드로 직접 구현하는 경우에 super를 부르면 안 되는지,
2. 왜 인터페이스 빌더에서 그린 뷰 컨트롤러의 클래스 파일에서 loadView 메서드를 오버라이드 하면 안 되는지
아시는 분이 있으시다면 댓글로 알려주세요!!