본문 바로가기
Swift

화면 전환

by JDeoks 2023. 6. 29.

 

present(_:animated:completion:)

present(_:animated:completion:)는  UIViewController를 모달로 표시하는 메소드이다.

여기서 모달이란, 창이 닫힐 때까지 그 창을 제외한 다른 부분은 반응할 수 없도록 잠기는 것을 의미한다. 

기존 뷰 컨트롤러위에 새로운 뷰 컨트롤러를 겹쳐서 보여주는 방식이다.

present(viewControllerToPresent: UIViewController, animated: Bool, completion: (() -> Void)?)
// 예시
let modalViewController = ModalViewController()
present(modalViewController, animated: true, completion: nil)


viewControllerToPresent: 모달로 표시할 UIViewController 인스턴스
animated: 모달 표시에 애니메이션을 사용할지 여부를 나타내는
completion: 모달 표시 애니메이션 완료 후 실행할 클로저

 

VC1이 VC2를 띄웠을 경우,

VC1에서는 presentedViewController 속성으로 VC2를 참조할 수 있고, VC2에서는 presentingViewController로 VC1을 참조할 수 있다.

dismiss(animated:completion:)

모달로 표시된 뷰컨트롤러를 닫는 메소드이다.

모달로 표시된 뷰 컨트롤러를 닫고, 이전의 뷰 컨트롤러로 돌아간다.

dismiss(animated: Bool, completion: (() -> Void)?)
// 예시
dismiss(animated: true, completion: nil)

animated: 모달을 닫을 때 애니메이션을 사용할지 여부를 나타내는 
completion: 모달 닫기 애니메이션이 완료된 후 실행할 클로저

dismiss를 실행하는 것은 VC2가 아니라 자신을 호출한 VC1이다.

따라서, VC2에서 self.presentingViewController.dismiss() 로 호출해야한다.

 

present 예제

새 뷰 컨트롤러 추가 후, ID 인스펙터에서 Storyboard ID 입력

//
//  ViewController.swift
//  Scene-Transition

import UIKit

class ViewController: UIViewController {

    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view.
    }

    @IBAction func moveNext(_ sender: Any) {
        let uvc: UIViewController? = self.storyboard?.instantiateViewController(identifier: "SecondVC")
        uvc?.modalPresentationStyle = UIModalPresentationStyle.formSheet
        self.present(uvc!, animated: true)
    }
}

self.storyboard

현재 뷰 컨트롤러가 속한 UIStoryboard

instantiateViewController(identifier:)

스토리보드에서 ID로 뷰 컨트롤러를 찾아 인스턴스를 생성

 

스토리보드가 여러 개 있을 경우

let storyboard = UIStoryboard(name: "Main", bundle: Bundle.main)
let uvc = storyboard.instantiateViewController(identifier: "SecondVC")

dismiss 예제

VC2에 연결할 새 클래스를 생성

//
//  SecondViewController.swift
//  Scene-Transition

import Foundation
import UIKit

class SecondViewController: UIViewController {
    override func viewDidLoad() {
        super.viewDidLoad()
    }
}

그 후 새 뷰컨트롤러에 만든 클래스를 연결

//
//  SecondViewController.swift
//  Scene-Transition

import Foundation
import UIKit

class SecondViewController: UIViewController {
    override func viewDidLoad() {
        super.viewDidLoad()
    }
    @IBAction func back(_ sender: Any) {
        dismiss(animated: true)
    }
}