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

ungchun·2022년 7월 7일
1
post-thumbnail

이번엔 현재 화면을 닫고 (dismiss) 바로 다음 화면을 열어야 하는 상황 (present) 이 생겼다. 구글링을 통해 알아낸 방법과 내가 쓴 방법을 한번 정리해보려 한다.

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 시켜주는 코드입니다.


navigationViewContorller 에서는 ? -> 참고 블로그 정리를 잘 해놓으셔서 참고해보면 될거 같습니다.

0개의 댓글