azhy의 iOS 이야기

[iOS/Swift] dismiss 하고 present 넘어가기 (Presented vs Presenting ViewController) 본문

Swift

[iOS/Swift] dismiss 하고 present 넘어가기 (Presented vs Presenting ViewController)

azhy 2024. 11. 12. 20:23

2022년 7월 7일에 작성됨

PresentedVC vs PresentingVC

먼저 이 두 개의 ViewController를 먼저 알아야 합니다.

 

PresentedViewController : 자신이 호출한 ViewController

PresentingViewController : 자신을 호출한 ViewController

 

이 친구들을 통해서 자신을 호출한 ViewController 가 있는지를 확인해서 dismiss 할 것인지에 대한 판단을 할 수 있습니다.

func dismiss(viewController: UIViewController) {
    if presentedViewController == viewController {
        dismiss(animated: true)
    }
}

extension UIViewController {
    func back() {
        if presentingViewController != nil { 
            dismiss(animated: true, completion: nil) // present
        } else {
            navigationController?.popViewController(animated: true) // push
        }
    }
}

 

dismiss 하고 present

// rootVC -> FirstVC -> SecondVC
self.dismiss(animated: true) {
  self.present(SecondViewController(), animated: true, completion: nil)
}

 

이렇게 작성해버리면 순서가 현재 자신인 FirstVC을 dismiss 하고 SecondVC로 present 하는 것이라 없어진 FirstVC을 가지고 present를 할 수 없습니다.

// rootVC -> FirstVC -> SecondVC
guard let pvc = self.presentingViewController else { return }

self.dismiss(animated: true) {
  pvc.present(SecondViewController(), animated: true, completion: nil)
}

 

그래서 presentingViewController (자신을 호출한 VC), 이 예시에서는 rootVC 가 됩니다. FirstVC 를 dismiss 해주고 설정해 놓은 pvc를 가지고 present 하는 거라 정상적으로 실행이 됩니다.

rootViewController 하위 viewController 삭제 후 present

self.view.window?.rootViewController?.dismiss(animated: true, completion: nil)

 

rootViewController 하위 viewController 를 단순히 지우고만 싶으면 이 코드를 쓰면 됩니다.

self.view.window?.rootViewController?.dismiss(animated: false, completion: {
    let newVC = NewViewController()  
    newVC.modalTransitionStyle = .crossDissolve
    newVC.modalPresentationStyle = .fullScreen
    self.present(newVC, animated: true, completion: nil)
})

 

이 경우는 페이지를 많이 넘어간 상태에서 작업이 마무리되고 쓸 수 있는 방법입니다.

예를 들어 rootVC -> FirstVC -> SecondVC -> ThirdVC에서 작업을 하다가 완료된 상태에서 새로운 newVC으로 넘어가야 하는 경우라면 rootViewController.dismiss로 하위 VC들을 dismiss 시키고 completion을 통해 dismiss가 끝나면 다음페이지로 넘어갈 newVC을 세팅해서 present 시켜주는 코드입니다.