[iOS] 화면전환 방법 (UINavigationController, UIViewController)

pom·2022년 11월 12일

프로젝트 중인 앱의 로그인 화면을 구현하던 중에, 로그인을 했을 때 앱의 기본 화면으로 넘어가는 동작을 구현하는 것에서 어려움을 겪었다.

이 과정에서 일반적인 뷰 컨트롤러를 사용하는 것과 네비게이션 컨트롤러를 사용해야하는 때를 구분할 수 있게 되어서, 공부한 내용을 정리해보려한다.

화면전환 방법 (Code Base)

  1. push, pop [UINavigationController]
  2. present, dismiss [UIViewController]

🎁 코드베이스로 화면 전환하기

🪅 push, pop

push, pop 메소드는 Navigation Controller에서 사용한다.

Navigation Controller는 화면들을 Stack 구조로 저장한다는 것이 가장 큰 특징이다.

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

  • navigation 인터페이스로 1개 이상의 view controller 를 관리할 수 있다.
  • Stack 기반이므로 최상단에 있는 하나의 view controller 만이 보여진다. 따라서 push 혹은 pop 을 통해 보여질 view controller 를 결정한다.
  • 선언시 기본이 될 root view controller 를 지정해야한다.
    즉 root view controller 위에 다른 viewControllers가 연결되는 것이다.
  • push 해서 들어갈 때 마다 이전의 정보를 저장해주고 있다. 따라서 pop을 통해 타고 돌아가는 것이 가능하다.

예시) 카카오톡 친구목록페이지에서 "친구의 생일을 확인해보세요!"를 눌렀을 때, 생일인 친구들을 보여주는 페이지로 넘어가는 것

🪅 present, dismiss

일반적인 뷰 컨트롤러에서는 present를 통해 다른 뷰컨트롤러를 나타낼 수 있다.
뷰 컨트롤러 위에 다른 뷰컨트롤러를 호출하는 것이다.

예시) 카카오톡 친구목록 페이지에서 친구의 프로필을 눌렀을 때, 프로필 화면(ViewController)이 친구목록화면(ViewController)위에 나타난다.

  • 단순한 덮어씌우기
  • 따라서 바로 전 뷰 컨트롤러에 대한 정보만 가지고 있다.
    • VC1 이 VC2를 present 하고, VC2가 VC3를 present 했다고 했을 때, VC3는 VC1에 접근할 수 없다.



🎁 결론

🪅 Navigation Controller를 이용하는 경우

  • 한 개의 루트뷰에서 여러 개의 화면을 이동해야할 때
  • 루트뷰에 대한 접근이 계속 필요할 때
  • navigationBar, toolBar를 이용하고 싶을 때

🪅 View Controller를 이용하는 경우

  • VC1 -> VC2 일회성 동작만 필요할 때


🎁 로그인 화면전환 구현

로그인 화면에서 앱 기본 화면으로 넘어갔을 때, 루트 뷰(로그인)에 대한 접근이 그 다음부터는 필요없어지므로 present를 통해 화면 전환을 구현했다.
그러나 자꾸 로그인화면에 앱 기본 화면이 중첩되어 보이는 거다.

modalPresentationStyle로 .fullscreen을 썼는데도 이런 현상이 계속됐다. --> 엥 다시 시도해보니 된다. Xcode오류였나

(뒤의 회색 뷰가 로그인화면이다.)

현재 있는 화면(로그인화면)을 dismiss 해서 닫은 후에 앱 기본 화면을 present해야겠다고 생각했다. 그래서 바로 dismiss 코드를 작성했다.

let tab = TabBarController() //앱 기본 화면들을 TabBarController로 연결했다.
        tab.modalPresentationStyle = .fullScreen //화면이 보여지는 방식
        present(tab, animated: true)
        dismiss(animated: true) 
        

이랬더니 로그인 화면이 아닌 앱 기본화면이 present 후 바로 dismiss되었다.

이는 구글링을 통해 해결 방법을 찾을 수 있었다.

🪅 PresentedVC vs PresentingVC

뷰컨트롤러는 presentedViewController, presentingViewController로 구분할 수 있다.


사진출처: https://velog.io/@leedool3003/iOS-dismiss-%ED%95%98%EA%B3%A0-present-%EB%84%98%EC%96%B4%EA%B0%80%EA%B8%B0-Presented-vs-Presenting-ViewController

  • presentedViewController: 호출받은 ViewController (나의 경우: 앱 기본 화면)
  • presentingViewController: 호출을 요청하고 있는 ViewController (나의 경우: 로그인 화면)

🪅 해결


//로그인 화면에서 앱의 메인 화면으로 전환 방법
 @objc func goToTab(){
        let tab = TabBarController()
        tab.modalPresentationStyle = .fullScreen //화면이 보여지는 방식
        tab.modalTransitionStyle = .crossDissolve //화면 전환 애니메이션
        
        //현재 화면을 닫고 tab열기
        present(tab, animated: true)
        
        if presentedViewController == tab { //호출된 화면이 탭이면
            presentingViewController?.dismiss(animated: true) //호출한 화면닫기
        }
    }
  
profile
Developer

0개의 댓글