관리 메뉴

김종권의 iOS 앱 개발 알아가기

[iOS - swift] Storyboard에 UI 구현, 코드에서 초기화하여 화면전환 하는 방법 (UIStoryboard, instantiateViewController) 본문

iOS 실전 (swift)

[iOS - swift] Storyboard에 UI 구현, 코드에서 초기화하여 화면전환 하는 방법 (UIStoryboard, instantiateViewController)

jake-kim 2020. 11. 8. 23:29

Storyboard객체 참조를 얻어서, 그 안에서 ViewController를 생성

  • "두 번째 화면"의 .swift구성
//
//  VC2.swift
//  TTTTT
//
//  Created by 김종권 on 2020/11/08.
//

import Foundation
import UIKit

class VC2: UIViewController {
    let storyboardName = "Main"
    let storyboardID = "VC2"
}
  • 다시, 스토리보드에서 Class와 Storyboard ID입력

  • 첫 번째 ViewController에서 Storyboard를 가지고 화면 초기화
    • storyboard객체를 storyboardName을 가지고 탐색
    • storyboard안에 기입한 storyboardID를 가지고 ViewController 초기화
    • storybaordName은 Storyboard파일 이름이며, storyboardID는 ViewController의 ID를 의미
//
//  ViewController.swift
//  TTTTT
//
//  Created by 김종권 on 2020/11/08.
//

import UIKit

class ViewController: UIViewController {

    override func viewDidLoad() {
        super.viewDidLoad()
    }

    @IBAction func btnNext(_ sender: Any) {

        let vc = VC2()
        let storyboardName = vc.storyboardName
        let storyboardID = vc.storyboardID

        let storyboard = UIStoryboard(name: storyboardName, bundle: Bundle.main)
        let viewController = storyboard.instantiateViewController(identifier: storyboardID)

        present(viewController, animated: true)
    }
}

MVVM에서의 Storyboard초기화 프로토콜

  • 새로운 ViewController 클래스를 만들 때, 아래 프로토콜을 구현
  • 화면 전환을 위해, 첫 번째 화면에서 두 번째 viewController를 생성할 때, VC2.instantiate(viewModel: vm)과 같이 초기화
protocol StoryboardInitializable {
    associatedtype ViewModel
    static var storyboardName: String { get set }
    static var storyboardID: String { get set }
    static func instantiate(viewModel: ViewModel) -> Self
    var viewModel: ViewModel! { get set }
    init?(coder: NSCoder, viewModel: ViewModel)
}

extension StoryboardInitializable where Self: UIViewController {

    static func instantiate(viewModel: ViewModel) -> Self {
        if #available(iOS 13.0, *) {
            let storyboard = UIStoryboard(name: storyboardName, bundle: Bundle.main)
            return storyboard.instantiateViewController(identifier: storyboardID) { (coder) -> Self? in
                return Self(coder: coder, viewModel: viewModel)
            }
        } else {
            let storyboard = UIStoryboard(name: storyboardName, bundle: Bundle.main)
            var vc = storyboard.instantiateViewController(withIdentifier: storyboardID) as! Self
            vc.viewModel = viewModel
            return vc
        }
    }
}

 

Comments