iOS

[ iOS ] Present된 화면 내린 후 처음 화면으로 돌아가기 (popToRootViewController, present, dismiss)

Forest Yun 2022. 4. 12. 13:41
728x90

공부한 내용을 정리한 글

 

 

 

문제

navigationController를 사용하다가 Present Modally를 한 경우 버튼 클릭 시 다시 처음 화면(RootViewController)으로 되돌아가기

 A(navigationController)  -push-    -Present-   

 

 

 

 

 


 

 

 

 

 

 

 C 가 Present된 Modal이기 때문에 그저 dismiss()메서드만 호출한다면  B 화면으로 돌아갈 뿐이다.

그렇다고 navigationController가 아닌  C 화면에서 UINavigaionController의 popToRootViewController()메서드를 사용할 수는 없다.

위 화면의 순서를 보면  A -는 NavigationController의 navigation Stack에 쌓인다.

따라서 popToRootViewController는 마지막, 즉 navigation Stack의 top인  B 에서 이루어져야 한다.

 

 

이 과정을 두 가지 방법으로 구현할 수 있다.

  1.  B 화면에서 present(_:animated:completion:) 를 사용해  C 화면이 나타난 직후 popToRootViewController()메서드를 호출해 처음 화면으로 돌아가기
  2.  C 화면에서 dismiss(animated:completion:)를 사용해  C 화면이 사라진 직후  B 화면을 이용해 popToRootViewController메서드 호출하여 처음화면으로 돌아가기

 

 

 

 

1. present(_:animated:completion:) 메서드를 사용하기

 B 화면의 뷰 컨트롤러

guard let C화면ViewController = self.storyboard?.instantiateViewController(withIdentifier: "C화면ViewController의 스토리보드ID") as? C화면ViewController else {return}
        
self.present(C화면ViewController, animated: true){
     self.navigationController?.popToRootViewController(animated: false)
}

 

 

1.1 present(_:animated:completion:) 메서드란?

뷰 컨트롤러를 prsent Modally 방식으로 화면에 띄우는 메서드.

이 메서드의 파라미터 중 하나인 completion은 클로저를 인자로 받는데, 이 클로저는 화면이 보여진 후 호출된다.

즉, C화면이 화면에 보여진 후 뒤에 A, B 순서로 쌓여있는 화면이 A화면만 남고 pop된다.

 

 

 

 

 

 

 

 

 

 

2. dismiss(animated:completion:) 메서드를 사용하기

 C 화면의 뷰 컨트롤러

guard let presentingViewController = self.presentingViewController as? UINavigationController else {return}
presentingViewController.popToRootViewController(animated: false)
        
self.dismiss(animated: true, completion: nil)

 

2.1 presentingViewController란?

현재 뷰 컨트롤러를 present한 뷰 컨트롤러를 의미한다. 즉, C화면에서의 presentingViewController는 B화면의 뷰 컨트롤러이다.

 

 

 

2.2 UINavigationController로 다운캐스팅 하는 이유

presentingViewController는 ViewController(UINavigationController의 부모)타입이다. 따라서 popToRootViewController()메서드를 사용하기 위해서는 UINavigationController로 다운캐스팅해야한다.

 

 

 

2.3 guard 문을 사용한 이유

prestingViewController는 현재 뷰 컨트롤러(C화면)가 present되지 않았거나 현재 뷰 컨트롤러의 조상(A, B) 중 present된 것이 없다면 nil이기 때문이다.

또 presentingViewController(B화면)이 UINavigationController 또는 그 서브클래스가 아니라면 다운캐스팅에 실패하기 때문이다.

 

 

 

 

 

 

 

 

 

 


 

 

 

 

 

 

 

 

 

Popview after dismiss modal view controller in swift
is와 as
728x90