Swift

[Swift] Xib, Storyboard의 ViewController를 불러오는 방법

hyeonii_12 2020. 11. 12. 18:35
반응형

Xib, Storyboard로 그린 ViewController 호출하기

Swift Version 5.3
Xcode Version 12.1

해당 내용은 초보 iOS 개발자의 입장에서 이해한 부분들에 대한 설명을 담고 있습니다.
오류가 있거나 수정되어야 할 내용이 있으면 언제든지 알려주세요.

이 글은 기존에 만들었던 프레임워크를 활용합니다!
프레임워크 생성은 아래 글을 참고해주세요.
[Swift] Framework 만들기

이전 글에서는 코드로만 작성되어 있던 뷰 컨트롤러를 다른 컨트롤러에서 불러오는 방법에 대해 설명했습니다.

1
2
let welcomeVC = WelcomeViewController()
self.present(welcomeVC, animated: true, completion: nil)
cs

하지만 뷰 컨트롤러를 그리기 위해서는 코드 뿐만 아니라 Xib, Storyboard 등을 통해 그릴 수도 있습니다.
이번에는 Xib, Storyboard로 그린 뷰 컨트롤러를 다른 컨트롤러에서 불러오는 방법에 대해 설명하고자 합니다.

1. Xib - 프레임워크에 파일 생성

프레임워크에 XibViewController라는 이름의 ViewController를 생성하였고 XIB 파일도 같이 생성했습니다.
앱에서 사용하기 위해 public 설정을 해 주었습니다.

Xib 파일에는 배경색만 노란색으로 바꾸었습니다.

2. Storyboard - 프레임워크에 파일 생성

우선 프레임워크에 StoryboardViewController라는 이름의 ViewController를 생성했습니다. 여기도 public 설정을 해 주어야 합니다.

StoryboardTest라는 이름의 스토리보드를 만들고 뷰 컨트롤러를 추가해서 배경색을 초록색으로 바꾸었습니다.

스토리보드에서 해당 "뷰 컨트롤러"를 선택하고 우측의 Identity Inspector 영역에서 class는 StoryboardViewController를 연결해주고(자동완성이 됩니다), Identity의 Storyboard ID에는 storyboardVC를 연결해 줍니다.스토리보드에서 뷰 컨트롤러를 선택하려다가 내부의 뷰를 선택하는 경우가 있어요.

헷갈리시는 분들은 스토리보드 파일 내부의 Document Outline에서 무엇이 선택되어 있는지 꼭 확인하세요!

class 연결 부분은
스토리보드에서 그린 뷰 컨트롤러와 StoryboardViewController.swift 파일로 나뉘어있던 걸 합쳐주는 작업이라고 생각하면 됩니다!
스토리보드의 뷰 컨트롤러는 화면만 있는거고 class 연결을 통해 해당 뷰 컨트롤러에 대한 코드로서의 처리를 StoryboardViewController.swift에서 하겠다-고 선언해주는 거죠.

Storyboard ID는
스토리보드에는 여러 개의 뷰 컨트롤러를 가질 수가 있는데요, 각각의 뷰 컨트롤러를 구분할 수 있도록 아이디를 부여하는 겁니다!
제가 방금 만든 초록색 뷰 컨트롤러에다가 storyboardVC라는 아이디를 주어서 다른 뷰 컨트롤러들과 구별할 수 있게 되었습니다.

3. 앱에서 불러오기

그러면 이제 본격적으로 앱에서 지금까지 만들었던 뷰 컨트롤러 들을 불러오도록 하겠습니다.
우선 기존에 만들었던 버튼 위에 두 개의 버튼을 추가로 만들었습니다.
어떤 뷰 컨트롤러를 불러오는 지 알 수 있도록 xib, storyboard라는 이름을 가지도록 했습니다.

xib

1
2
let xibVC = XibViewController(nibName: "XibViewController", bundle: Bundle(for: XibViewController.self))
self.present(xibVC, animated: true, completion: nil)
cs

XibViewController를 불러오기 위해서는 위와 같이 하면 됩니다.

UIViewController를 initialize 하는 아래의 함수를 사용한 건데요.

init(nibName: String?, bundle: Bundle?)

nibName은 뷰 컨트롤러를 그린 xib 파일의 이름을, bundle은 xib 파일이 있는 위치를 말합니다.
(코드로 뷰 컨트롤러를 생성할 때는 xib 파일이 없기 때문에 파라미터에 모두 nil을 넣어서 파라미터가 없는 것처럼 사용할 수 있었습니다.)

번들이 nil이면 해당 코드를 사용한 -뷰 컨트롤러를 생성한- 곳에서 뷰 컨트롤러를 찾게 되는데요,
우리는 프레임워크에 있는 뷰 컨트롤러를 사용하려고 하는 것이기 때문에 nil을 넣으면 앱에서는 해당 파일을 찾지 못하게 됩니다.
따라서 "XibViewController 파일이 있는 위치의 번들을 보면 XibViewController라는 이름의 nib 파일이 있을 건데 걔를 사용할 거야!"라고 말하는 셈이 되는 거죠!

번들에 대한 설명 때문에 같은 앱에서 파일을 만들지 않고 프레임워크에서 만들었던 겁니다.

그런데 사실 여기서 nibName에 nil을 넣어도 제대로 된 xib 파일을 찾는답니다!
애플 개발자 문서에 보면 그 이유가 나와있는데요, 그 내용까지 넣으면 너무 길어질 것 같아서 결론만 말하면 뷰 컨트롤러 클래스 이름과 xib 파일의 이름이 같기 때문입니다.
(자세한 내용은 nibName 을 참고하세요.)

자, 그러면 xib로 그린 뷰 컨트롤러를 어떻게 다른 뷰 컨트롤러에서 생성할 수 있는지 이해가 되셨나요?
그러면 이제 스토리보드로 넘어가 보겠습니다.

storyboard

1
2
let storyboardVC = UIStoryboard(name: "StoryboardTest", bundle: Bundle(for: StoryboardViewController.self)).instantiateViewController(withIdentifier: "storyboardVC"as! StoryboardViewController
self.present(storyboardVC, animated: true, completion: nil)
cs

우선 뷰 컨트롤러가 있는 스토리보드(UIStoryboard)를 생성하고, 그 안에 있는 뷰 컨트롤러를 인스턴스화 하는 방법입니다.

init(name: String, bundle: Bundle?)

name은 옵셔널이 아닙니다. 어떤 스토리보드를 쓸 건지 명시를 해줘야 하기 때문에 어떻게 보면 당연한 소리입니다.
bundle은 옵셔널이지만 위에서 설명한 대로 스토리보드의 위치가 프레임워크이기 때문에 여기서는 꼭 명시해줘야 합니다.

다음은 UIStoryboard 안에 있는 뷰 컨트롤러를 인스턴스화 하는 함수입니다.

func instantiateViewController(withIdentifier: String) -> UIViewController

withIdentifier에는 위에서 부여했던 Storyboard ID를 적어주면 됩니다.

그런데 여기서

func instantiateInitialViewController() -> UIViewController?

이 함수랑 헷갈리죠?
얘는 스토리보드의 첫 번째 뷰 컨트롤러를 불러오는 함수인데요, 우측의 Attributes Inspector 영역에서 View Controller의 Title 밑에
Is Initial View Controller라고 되어있는 부분을 클릭해서

이렇게 뷰 컨트롤러 옆에 화살표를 만들면
스토리보드 아이디 없이도 해당 뷰 컨트롤러를 가져올 수 있답니다!
다만 스토리보드에는 많은 뷰 컨트롤러들이 있을 수 있으므로 해당 뷰 컨트롤러가 이 스토리보드의 첫 번째 화면이 되어도 괜찮은지 꼭 확인해주세요.

마지막으로 이렇게 불러온 뷰 컨트롤러가 StoryboardViewController임을 명시해주면 됩니다.

as! StoryboardViewController

4. Run!

잘 나오는 것을 확인할 수 있습니다!

반응형