본문 바로가기
iOS/설명

[iOS] nibName에 따른 ViewController 초기화

by Sky Titan 2023. 1. 21.
728x90

https://developer.apple.com/documentation/uikit/uiviewcontroller/1621359-init

 

Apple Developer Documentation

 

developer.apple.com

https://developer.apple.com/documentation/uikit/uiviewcontroller/1621487-nibname

 

Apple Developer Documentation

 

developer.apple.com

init(nibName:bundle:)

지정된 bundle에서 nibName을 통해 nib파일을 찾아 새로운 UIViewController 인스턴스를 만들어내는 함수

 

Discussion

 UIViewController의 designated initializer이다.

 storyboard에서 ViewController를 정의하면, 직접적으로 class를 init해서 생성할 수가 없다. 대신에 initiateViewController(identifier:) 메서드를 이용하여 segue가 트리거될 때, 자동으로 ViewController를 초기화 시켜준다.

 storyboard에서 ViewController를 초기화할 때, init(coder:) 메서드를 활용하고 이 때 storyboard안에 저장된 nib file로 nibName 프로퍼티를 지정한다.

 

 이 메서드를 통해 nibName을 지정하더라도, 바로 nib file이 로드되지는 않고 ViewController의 view에 최초로 접근할 때 로드된다. 그렇기 때문에 nib 파일이 로드된 이후에 초기화와 관련된 작업을 하고 싶다면 viewDidLoad() 메서드에서 수행해야한다.

 

 만약 nibName을 지정하지 않고 loadView() 메서드를 오버라이드 하지 않았다면, ViewController는 본인 class의 이름을 기반으로 nib 파일을 찾게 된다.

 

nibName이 nil일 시, ViewController nib 파일을 찾는 규칙

 일반적으론 nibName을 명시적으로 지정해주는게 권장되지만, 지정되지 않았다면 아래 2가지 규칙 중 하나에 부합하는 이름을 가진 nib파일을 불러오게 된다. (확장자 '.nib' 은 제외한다)

  1. 만약 viewController의 클래스 이름이 'Controller'로 끝나는 경우, 'Controller'를 제외한 나머지 class이름과 일치하는 nib 파일을 찾게 된다.
    • class 이름이 'MyViewController'라면 'MyView.nib' 이라는 파일을 찾게 된다.
  2. ViewController의 클래스 이름과 일치하는 nib 파일을 찾아온다.
    • class 이름이 'MyViewController'라면 'MyViewController.nib'이라는 파일을 찾게 된다.
Note
Nib 이름이 플랫폼 이름을 포함한다면 해당 플랫폼의 디바이스에서만 로드된다.
예를 들어, MyViewController~ipad.nib은 ipad에서만 로드된다.

 

nibName규칙에 따라 ViewController load해오는 예시

import UIKit

class ViewController: UIViewController {
    
    override func viewDidLoad() {
        super.viewDidLoad()
    }
    
    
    @IBAction func buttonClicked(_ sender: Any) {
    //Button click시 RedViewController를 띄운다.
        let redVC = RedViewController()
        redVC.modalPresentationStyle = .fullScreen
        self.present(redVC, animated: true)
    }
}

//띄워지는 ViewController
class RedViewController: UIViewController {
    
    override func viewDidLoad() {
        super.viewDidLoad()
        print("Red viewController viewDidLoad \(nibName)")
    }
    
    @IBAction func close(_ sender: Any) {
        dismiss(animated: true)
    }
}

 위와 같이 ViewController에서 버튼을 클릭 시 RedViewController라는 화면을 띄워야 한다.

 

1. nibName이 'RedView.nib'인 경우

 xib의 이름은 'RedView.xib'로 하여 nib파일이 인코딩 되었을 때 'RedView.nib'이 되는 경우, 정상적으로 화면이 load된다.

RedView.xib
ViewController의 nibName프로퍼티가 'RedView'로 지정된 것을 확인할 수 있다.

 

2. nibName이 'RedViewController.nib'인 경우

xib의 이름은 'RedViewController.xib'로 하여 nib파일이 인코딩 되었을 때 'RedViewController.nib'이 되는 경우, 정상적으로 화면이 load된다.

ViewController의 nibName프로퍼티가 'RedViewController'로 지정된 것을 확인할 수 있다.

3. nibName이 'Red.nib'인 경우

xib의 이름은 'Red.xib'로 하여 nib파일이 인코딩 되었을 때 'Red.nib'이 되는 경우, nibName 규칙과 일치하는 nib 파일을 찾지 못하여 정상적으로 화면이 load되지 않는다.

 

ViewController의 nibName프로퍼티가 nil이다.

728x90

댓글