본문 바로가기
iOS (Swift)

[오늘의 코드 조각] [iOS 5-1] 화면 전환의 모든 것: Navigation Controller, TabBar Controller, 그리고 Segue의 한계

by 생각하는 개발자님 2026. 7. 14.
반응형

안녕하세요! [생각하는 개발자]입니다.

우리는 지난 4부를 통해 현업 수준의 깔끔한 Git 협업 프로세스(Git-Flow, PR)를 완벽하게 정복했습니다. 이제 튼튼한 협업의 기반 위에서, 본격적으로 앱의 거대한 지도를 그려나갈 차례입니다.

오늘 다룰 주제는 바로 화면 전환(Navigation)입니다. 앱에서 화면이 전환되는 방식은 단순한 '시각 효과'가 아니라, 사용자가 앱과 상호작용하는 흐름(UX) 그 자체를 결정합니다. iOS UIKit이 제공하는 대표적인 화면 전환 구조와 함께, 스토리보드가 제공하는 편리하지만 치명적인 독배인 Segue(세그웨이)의 실무적 한계까지 낱낱이 파헤쳐 보겠습니다.

5_5 Navigation, TabBar 그리고 Segue가 외면받는 이유
5_5 Navigation, TabBar 그리고 Segue가 외면받는 이유

5.1.1 캔버스 위에 재료 얹기 (iOS 화면 전환의 2대 축)

iOS에서 화면을 전환하는 물리적인 방법은 크게 두 가지 흐름으로 나뉩니다.

  • 가로의 흐름: TabBar Controller
    • 하단에 탭 버튼이 있어 각각 완전히 독립된 기능(예: 홈, 검색, 설정)을 평행하게 오갈 때 사용합니다.
  • 세로(깊이)의 흐름: Navigation Controller
    • 정보를 탐색하며 점점 깊숙한 상세 화면으로 들어갔다가 다시 돌아오는 흐름(예: 메일 리스트 ➔ 메일 본문)에 사용합니다.
// 5.1.2 단계별 실습을 위한 코드 전환 기본형
// 1. 단순 팝업처럼 화면을 위로 띄우는 방식 (Present/Modal)
let detailVC = DetailViewController()
self.present(detailVC, animated: true, completion: nil)

// 2. 우측에서 좌측으로 화면을 밀어넣는 방식 (Push - Navigation Controller 필수)
self.navigationController?.pushViewController(detailVC, animated: true)

5.1.2 [단계별 실습] 화면 전환의 4가지 방식과 철학

화면을 전환할 때는 단순히 "이 효과가 예쁘니까"가 아니라, 콘텐츠의 흐름과 목적에 맞춰 올바른 전환 방식을 선택해야 합니다.

1단계: Navigation Push & Pop (정보의 흐름)

  • 어떻게 작동하나요?: 책장을 넘기듯 화면이 우측에서 좌측으로 밀려 들어옵니다. 뒤로 갈 때는 좌측 상단의 Back 버튼을 누르거나 화면 왼쪽 끝을 스와이프(interactivePopGestureRecognizer)합니다.
  • 언제 쓰나요?: 게시글 리스트에서 상세 글 보기처럼, 이전 화면과의 맥락이 끊기지 않고 깊이(Depth) 있게 탐색해 들어가는 흐름에 사용합니다.

2단계: Present & Dismiss (모달 - 흐름의 차단)

  • 어떻게 작동하나요?: 화면이 아래에서 위로 슬라이드하며 기존 화면을 덮어씌웁니다.
  • 언제 쓰나요?: 글쓰기 화면, 로그인 화면처럼 "지금 하던 일을 멈추고 이 작업에 집중해서 끝내거나 취소해라" 하는 독립된 태스크(Task)를 줄 때 사용합니다.

3단계: 스토리보드가 제공하는 치트키, Segue(세그웨이)

스토리보드상에서 컴포넌트(예: 버튼)를 마우스 우클릭한 뒤 목적지 뷰 컨트롤러로 선을 쓱 그으면, 한 줄의 코드 없이도 화면 전환이 일어납니다. 이 연결선을 Segue라고 부릅니다.

  • 장점: 코딩 없이 빠르게 화면 전환을 구현할 수 있고, 앱의 전체적인 화면 흐름을 시각적으로 파악하기 좋습니다.

⚠️ [생각하는 한 스푼] 실무에서 Segue(세그웨이)가 외면받는 이유

프로젝트가 커질수록 현업 개발자들은 스토리보드의 Segue를 점차 멀리하고, 코드로 화면 전환을 직접 제어하기 시작합니다. 왜 편리한 툴을 두고 사서 고생을 할까요?

  1. 지나치게 높은 결합도(Tight Coupling): Segue를 통해 데이터를 전달하려면 prepare(for:sender:)라는 무겁고 투박한 메서드 하나에 모든 화면 전환 분기 처리를 때려 박아야 합니다. 이 과정에서 타입 캐스팅(as?)과 String 기반의 identifier 식별자 조회가 엉켜 스파게티 코드가 되기 쉽습니다.
  2. 동적 제어의 한계: "로그인이 성공했을 때만 다음 화면으로 넘어가라" 같은 비즈니스 로직을 중간에 끼워 넣기가 까다롭습니다. 버튼을 누르면 무조건 선을 타고 화면이 넘어가 버리기 때문이죠.
  3. 협업의 난제: 4부에서 배웠듯, 스토리보드 한 장에 수십 개의 Segue가 얽혀 있으면 여러 개발자가 동시에 작업할 때 .storyboard 파일에 끔찍한 충돌이 발생합니다.

💡 현업 실무 처방전: 그래서 현업에서는 화면 단위를 작은 스토리보드 여러 개로 쪼개거나, 아예 스토리보드를 쓰지 않고 Code-based UI(코드로 짜는 UI) 환경에서 Coordinator 패턴 등을 도입해 화면 전환 로직을 뷰 컨트롤러 밖으로 완전히 격리하는 설계를 지향합니다.

👨‍💻 안드로이드 개발자와의 비교 조각

안드로이드에서 화면을 전환할 때 Intent를 만들어 startActivity()를 호출했던 기억이 있으실 겁니다.

이때 화면이 전환되는 기본 애니메이션은 보통 우측에서 좌측으로 밀려 들어오는 형태(iOS의 Push와 유사)였습니다. 안드로이드에서는 이 기본 전환 위에 뒤로 가기(Back button)를 OS 차원의 물리 버튼으로 처리하죠.

반면 iOS는 물리 뒤로 가기 버튼이 없기 때문에 Navigation Bar의 Back 버튼 영역이나 Edge Swipe 제스처가 OS 표준 UX로 자리 잡았습니다. 또한, 안드로이드의 독립된 창 구조인 Dialog나 BottomSheet 개념이 iOS에서는 Present 메서드의 modalPresentationStyle 옵션(.pageSheet, .formSheet 등)을 통해 시스템적으로 아름답게 내장되어 제공된다는 것도 눈여겨볼 만한 인터페이스 철학의 차이입니다.

🎯 오늘의 요약

  • Push/Pop은 깊이 있는 정보 탐색에, Present/Dismiss(Modal)은 현재 흐름을 끊고 집중해야 하는 태스크에 사용한다.
  • TabBar Controller는 대등한 가치의 기능들을 평행하게 전환할 때 사용된다.
  • Segue는 초반 프로토타이핑에는 유용하지만, 대형 프로젝트 협업과 유연한 아키텍처 관점을 고려할 때 실무에서는 기피되는 편이다.

화면 전환의 규칙과 철학을 이해하면 단순한 기능 구현을 넘어 "사용하기 편한 앱"을 설계할 수 있습니다.

다음 장 [iOS 5-2]에서는 화면이 전환될 때 메모리가 생성되고 수거되는 원리와 맞물리는, 면접 단골 질문 ViewController의 데이터 전달 패턴 실무 구현으로 돌아오겠습니다. 생각하는 개발자가 되어 함께 깊이를 더해갑시다!

반응형