iOS의 화면 전환 방식은 크게 4가지 정도로 나눌 수 있다.
- 뷰 컨트롤러의 뷰 위에 다른 뷰를 가져와 바꿔치기 (Container View Controller 사용)
- 뷰 컨트롤러에서 다른 뷰 컨트롤러를 호출하여 화면 전환
- 내비게이션 컨트롤러를 사용하여 화면 전환
- 화면 전환용 객체 세그웨이(Sequeway)를 사용하여 화면 전환하기
iOS에서 화면 전환은 다음의 2가지 특성을 가진다.
- 다음 화면으로 이동하는 방법과 이전 화면으로 되돌아가는 방법이 다름
- 화면 전환 방식에 따라 이전 화면으로 되돌아가는 방법이 다름
화면 전환 기법 1. 뷰를 이용한 화면 전환 (비추천)
하나의 뷰 컨트롤러 안에 두개의 루트 뷰를 준비하고, 상태에 따라 뷰를 적절히 교체해주는 방식이다.
뷰를 완전히 바꿔치기 할 수도 있고, 기존 뷰 위에 다른 뷰를 덮어서 가려지게만 할 수도 있다.
하지만 하나의 뷰 컨트롤러가 2개 이상의 루트 뷰를 관리해야 하므로 좋은 방법은 아님. (MVC 패턴을 거스르기 때문에)
뷰를 이용하여 화면을 전환하면서 하나의 뷰 컨트롤러가 하나의 루트 뷰만 관리하도록 할 수도 있다.
아래 그림처럼 다른 뷰 컨트롤러에 올려진 루트 뷰를 가져와 표시해주는 것이다.
하지만 이 방법도 기존 뷰 컨트롤러가 관리하던 뷰가 다른 뷰 컨트롤러로 옮겨가게 되어서 뷰를 제어할 책임이 있는 컨트롤러가 모호해진다는 단점이 있다. 또한 이후에 내비게이션 컨트롤러를 사용하여 화면 전환 시 루트 뷰와 뷰 컨트롤러의 불일치 현상이 발생할 수도 있다.
뷰를 이용한 화면 전환은 고려해야할 사항이 많다. 따라서 되도록이면 뷰를 이용한 화면 전환보다는 뷰 컨트롤러를 이용한 화면 전환 방식을 사용하는 것이 좋다.
화면 전환 기법 2. 뷰 컨트롤러 직접 호출에 의한 화면 전환
현재의 뷰 컨트롤러에서 이동할 대상 뷰 컨트롤러를 직접 호출해서 화면을 표시해준다. (프레젠테이션 방식)
기존의 뷰 컨트롤러는 그대로 둔 채, 그 위에 새로운 뷰 컨트롤러의 화면을 덮는 방식이다.
UIViewController 클래스에 정의된 다음 메소드를 통해 화면을 전환할 수 있다.
- 첫번째 인자값 : 새로운 화면을 담당하는 뷰 컨트롤러의 인스턴스
- 두번째 인자값 : 애니메이션 효과 적용 여부 (true / false)
// 화면 전환 메소드 (호출 대상 : 뷰 컨트롤러 자신)
present(_:animated:)
present(<새로운 뷰컨트롤러 인스턴스>, animated:<애니메이션 여부>)
화면 전환이 완료되는 시점에 맞춰서 특정 로직을 실행해 주어야 할 경우에는 아래의 메소드를 사용한다.
세번째 매개변수에는 실행 구문을 클로저나 함수 형식으로 입력받아서, 화면 전환이 완전히 끝난 후에 호출해준다.
화면 전환은 비동기 방식으로 이루어지기 때문에 단순히 present() 메소드 이후에 입력된 코드가 화면 전환 후에 실행된다는 보장이 없다. 따라서 화면 전환이 완전히 끝난 뒤에 실행할 구문이 있다면 3번째 인자값으로 실행할 내용을 넘겨주어야 한다.
// 화면 전환 완료 시점에 특정 로직 수행
present(_:animated:completion:)
프레젠테이션 방식으로 화면이 전환되면 양쪽 뷰 컨트롤러 사이에는 서로를 참조할 수 있는 포인터가 생성된다.
- presentedViewController : 기존 뷰 컨트롤러 -> 새로운 뷰 컨트롤러
- presentingViewController : 새로운 뷰 컨트롤러 -> 기존 뷰 컨트롤러
이전 화면 복귀 시에는 아래의 메소드를 사용한다.
이전 화면 복귀에서는 뷰 컨트롤러의 인스턴스를 인자값으로 받을 필요 없다.
// 이전 화면 복귀 메소드
// (호출 대상 : 현재의 뷰 컨트롤러를 표시해준 컨트롤러 ==> self.presentingViewController)
dismiss(animated:)
// 화면 복귀 완료 시점에 특정 로직 수행
dismiss(animated:completion:)
여기서 주의할 점은 화면을 걷어내는 주체는 자기 자신이 아닌 자신을 띄우고 있는 이전 뷰 컨트롤러라는 것이다. 따라서 메소드 호출은 아래와 같은 방식이 아니라
self.dismiss(animated:)
아래와 같이 presentingViewController 포인터를 참조하여 메소드를 호출해야 한다.
self.presentingViewController?.dismiss(animated:)
화면 전환 기법 3. 내비게이션 컨트롤러를 이용한 화면 전환
내비게이션 컨트롤러(UINavigationController)는 뷰 컨트롤러의 특별한 종류로, 계층적인 성격을 띠는 콘텐츠 구조를 관리하기 위한 컨트롤러이다.
내비게이션 컨트롤러는 다른 뷰 컨트롤러들을 제어하며 화면을 전환시킨다. 또한 내비게이션 바(Navigation Bar)가 내장되어 있다는 특징이 있으며, 화면 전환이 발생하는 뷰 컨트롤러들의 포인터를 스택(Stack)으로 관리한다.
콘텐츠 계층 구조에서 시작점 역할을 하는 뷰 컨트롤러는 루트 뷰 컨트롤러(Root View Controller)라고 한다.
내비게이션 컨트롤러가 뷰 컨트롤러들을 관리할 때는 내비게이션 스택(Navigation Stack)을 사용한다.
스택의 최상위에 뷰 컨트롤러를 추가하거나 제거할 때는 아래의 메소드를 사용한다. 이 메소드를 통해 화면 전환이 이루어진다.
// 뷰 컨트롤러 추가
// (호출 대상 : 내비게이션 컨트롤러 ==> self.navigationController)
pushViewController(_:animated:)
// 뷰 컨트롤러 제거
// (호출 대상 : 내비게이션 컨트롤러 ==> self.navigationController)
popViewController(animated:)
화면 전환 기법 4. 세그웨이를 이용한 화면 전환 (가장 편리한 방법)
세그웨이(Segue)라는 객체는 스토리보드에서 뷰 컨트롤러 사이의 연결 관계 및 화면 전환을 관리한다.
세그웨이는 화면과 화면을 연결하기 위해 별도의 소스 코드를 작성할 필요가 없고, 뷰 컨트롤러와 버튼 사이를 직접 연결해주는 방식으로 화면 전환 관계를 구성해준다.
세그웨이는 스토리보드 상에서 뷰 컨트롤러 사이에 있는 화살표로 표시된다. 이 때 화살표는 한쪽으로만 흐르는 일방통행이다.
세그웨이를 사용하면 알아서 스토리보드 상의 연결 정보를 바탕으로 뷰 컨트롤러 인스턴스를 생성해주기 때문에 직접 뷰 컨트롤러 객체를 생성할 필요가 없다.
화면 전환이 목적이기 때문에 세그웨이의 목적지는 당연히 뷰 컨트롤러이다. 하지만 출발점은 뷰 컨트롤러 자체가 될 수도 있고, 버튼이나 테이블 셀 등의 컨트롤이 될 수도 있다.
- 매뉴얼 세그웨이(Manual Segue) : 출발점이 뷰 컨트롤러일 경우
- 액션 세그웨이(Action Segue) 또는 트리거 세그웨이(Trigger Segue) : 출발점이 버튼 등의 오브젝트일 경우
두 방식 모두 세그웨이를 실행하기만 하면 화면 전환이 이루어지는데, 세그웨이의 실행 방식이 조금씩 다르다.
매뉴얼 세그웨이를 실행할 때는 UIKit에 정의된 다음 메소드를 사용한다. 매뉴얼 세그웨이는 액션 세그웨이와 다르게 뷰 컨트롤러와 뷰 컨트롤러 사이에 연결되는 수동 실행 세그웨이이다.
performSegue(withIdentifier: <세그웨이 식별자>, sender: <세그웨이 실행 객체>)
액션 세그웨이는 버튼의 터치 이벤트가 세그웨이 실행으로 바로 연결되기 때문에 소스코드를 추가하지 않아도 화면 전환이 구현 가능하다.
또한 세그웨이 사용 시에는 스토리보드에 화면 전환 관계가 직관적으로 표시되기 때문에 화면 사이의 관계를 파악하기 쉽다.
어떤 버튼을 클릭했을 때 조건 여부와 관계 없이 무조건 특정 페이지로 이동하게 처리하려면 액션 세그웨이를 사용해 주는 것이 편리하다.
하지만 다양한 조건에 다라 이동하는 페이지를 다르게 제어하고 싶을 경우에는 매뉴얼 세그웨이를 사용해준다.
'iOS' 카테고리의 다른 글
[ iOS ] 화면 전환 시 값 전달 방식 (UIKit) (0) | 2023.02.15 |
---|---|
[ iOS ] Unwind - 화면 복귀 (UIKit) (0) | 2023.02.13 |
[ iOS ] 코코아 터치 프레임워크의 주요 프레임워크와 접두어 정리 (0) | 2023.02.08 |
[ iOS ] iOS 앱의 생명 주기 (UIKit) (0) | 2023.02.08 |
[ iOS ] 개발 시 기본적인 용어 정리 (UIKit) (0) | 2023.02.07 |