프로젝트 중인 앱의 로그인 화면을 구현하던 중에, 로그인을 했을 때 앱의 기본 화면으로 넘어가는 동작을 구현하는 것에서 어려움을 겪었다.
이 과정에서 일반적인 뷰 컨트롤러를 사용하는 것과 네비게이션 컨트롤러를 사용해야하는 때를 구분할 수 있게 되어서, 공부한 내용을 정리해보려한다.
화면전환 방법 (Code Base)
- push, pop [UINavigationController]
- present, dismiss [UIViewController]
push, pop 메소드는 Navigation Controller에서 사용한다.
Navigation Controller는 화면들을 Stack 구조로 저장한다는 것이 가장 큰 특징이다.

애플 공식 문서에 따르면, 계층적 내용을 탐색하기 위한 스택 기반 스키마를 정의하기 위한 컨테이너 뷰 컨트롤러다. 다음과 같이 시계 앱도 계층적 내용으로 구성이 되어있다.


예시) 카카오톡 친구목록페이지에서 "친구의 생일을 확인해보세요!"를 눌렀을 때, 생일인 친구들을 보여주는 페이지로 넘어가는 것
일반적인 뷰 컨트롤러에서는 present를 통해 다른 뷰컨트롤러를 나타낼 수 있다.
뷰 컨트롤러 위에 다른 뷰컨트롤러를 호출하는 것이다.
예시) 카카오톡 친구목록 페이지에서 친구의 프로필을 눌렀을 때, 프로필 화면(ViewController)이 친구목록화면(ViewController)위에 나타난다.
로그인 화면에서 앱 기본 화면으로 넘어갔을 때, 루트 뷰(로그인)에 대한 접근이 그 다음부터는 필요없어지므로 present를 통해 화면 전환을 구현했다.
그러나 자꾸 로그인화면에 앱 기본 화면이 중첩되어 보이는 거다.
modalPresentationStyle로 .fullscreen을 썼는데도 이런 현상이 계속됐다. --> 엥 다시 시도해보니 된다. Xcode오류였나
(뒤의 회색 뷰가 로그인화면이다.)
현재 있는 화면(로그인화면)을 dismiss 해서 닫은 후에 앱 기본 화면을 present해야겠다고 생각했다. 그래서 바로 dismiss 코드를 작성했다.
let tab = TabBarController() //앱 기본 화면들을 TabBarController로 연결했다.
tab.modalPresentationStyle = .fullScreen //화면이 보여지는 방식
present(tab, animated: true)
dismiss(animated: true)
이랬더니 로그인 화면이 아닌 앱 기본화면이 present 후 바로 dismiss되었다.
이는 구글링을 통해 해결 방법을 찾을 수 있었다.
뷰컨트롤러는 presentedViewController, presentingViewController로 구분할 수 있다.
//로그인 화면에서 앱의 메인 화면으로 전환 방법
@objc func goToTab(){
let tab = TabBarController()
tab.modalPresentationStyle = .fullScreen //화면이 보여지는 방식
tab.modalTransitionStyle = .crossDissolve //화면 전환 애니메이션
//현재 화면을 닫고 tab열기
present(tab, animated: true)
if presentedViewController == tab { //호출된 화면이 탭이면
presentingViewController?.dismiss(animated: true) //호출한 화면닫기
}
}