iOS - 꼼꼼한 재은씨 Swift 기본편(2_화면 전환)

이한솔·2023년 11월 16일
0

iOS 앱개발 🍏

목록 보기
27/49

화면 전환

뷰를 이용한 화면 전환

하나의 뷰컨트롤러 안에 두개의 루트뷰를 준비한 다음 상태에 따라 뷰를 적절히 교체해준다. 필요에 따라 뷰를 완전히 바꿔치기 할 수도 있고 단순히 기존 뷰 위에 다른 뷰를 덮어 가려지게만 할 수도 있다. 그러나 이 방법은 하나의 뷰컨트롤러가 두 개 이상의 루트뷰를 관리해야하므로 좋은 방법이 아니다. 될 수 있으면 뷰를 이용한 화면 전환은 지양하는것이 좋다.



다른 뷰컨트롤러를 호출하여 화면 전환

현재의 뷰컨트롤러에서 이동할 대상 뷰컨트롤러를 직접 호출해서 화면을 표시하는 방식이다. 직접 표시한다는 의미에서 프레젠테이션 방식이라고 부른다.

present(_:animated:)

// 화면 전환이 완료되는 시점에 맞추어 특정 로직을 실행해주어야 할 때
present(_:animated:completion:)

프레젠테이션 방식으로 화면을 전환했을 때 iOS 시스템은 화면에 표시된 뷰컨트롤러와(Presented, VC1) 표시하고 있는 뷰컨트롤러(Presenting, VC2) 사이에 참조할 수 있는 포인터를 생성하여 서로 참조할 수 있게 해준다.
VC1에서는 presentedViewController 속성에 자신이 표시하고 있는 VC2를 저장하고, VC2에서는 presentingViewController 속성에 자신을 표시한 VC1의 포인터를 저장한다.

이전화면으로 돌아가야하는 경우에 기존 화면이 새로운 화면 위로 올라오는 것이 아니라 기존 화면을 덮고 있던 새 화면을 걷어낸다. 화면을 걷어내는 주체는 자기 자신이 아니라 자신을 띄우고 있던 이전 화면으로 뷰컨트롤러 인스턴스에 대한 참조 포인터 presentingViewController 를 통해 화면을 내려달라고 요청한다.
걷어낸 화면의 뷰컨트롤러 객체는 운영체제에 의해 곧 메모리에서 해제된다.

dismiss(animated:)

dismiss(animated:completion:)

// 이전 화면의 뷰컨트롤러 
self.presentingViewController?.dismiss(animated:)

💡 Unwind?

iOS 앱에서 이전 화면으로 돌아가는 것
프레젠테이션 방식으로 화면을 전환할 경우, 뷰컨트롤러의 포인터는 차례로 프레젠테이션 체인에 저장된다. 그리고 이전 화면으로 되돌아가는 과정은 이 프레젠테이션 체인에 저장된 뷰컨트롤러의 포인터를 제거하는 방식이다. 포인터가 제거된 뷰컨트롤러들은 ARC 시스템에 의해 메모리에서 차례로 해제된다. Unwind 메소드는 단순히 화면 복귀가 아니라 이같은 역할도 처리한다. 화면 전환 방식에 따라 맞는 Unwind 메소드를 사용해야 한다.



내비게이션 컨트롤러를 사용한 화면 전환

내비게이션 컨트롤러는 계층적인 성격을 띠는 콘텐츠 구조를 관리하기 위한 컨트롤러이다. 내비게이션 바가 내장되어있다. 뷰 컨트롤러들의 전환을 직접 컨트롤하고, 앱의 내비게이션 정보를 표시하고 화면 전환이 발생하는 뷰컨트롤러들의 포인터를 스택으로 관리한다. 스택은 배열 형식으로 되어있다.
스택의 뷰컨트롤러를 추가하거나 제거해서 화면을 이동한다.
내비게이션 컨트롤러를 통해 화면을 이동할때는 메소드를 호출하는 대상이 뷰컨트롤러가 아니라 내비게이션 컨트롤러이다. 내비게이션 컨트롤러로 화면을 이동하면 자동으로 내비게이션 바에 뒤로가기 버튼을 만들어준다. 버튼을 커스텀 할 수도 있지만 커스텀 할 때는 뒤로가기 기능을 직접 구현해줘야한다.

// 추가 메소드
pushViewController(_:animated:)

// 제거 메소드
popViewController(animated:)


세그웨이(Segueway)를 사용한 화면 전환

세그웨이는 스토리보드에서 뷰컨트롤러 사이의 연결 관계 및 화면 전환을 관리하는 역할을 한다. 세그웨이로 화면전환시 스토리보드 상의 연결 정보를 이용하여 뷰컨트롤러의 인스턴스를 자동으로 만들어서 뷰컨트롤러의 객체를 생성할 필요가 없다.
세그웨이가 실행되면 스토리보드를 통해 세그웨이의 출발지와 목적지 뷰컨트롤러에 대한 인스턴스가 생성되고 그 포인터가 세그웨이 객체에 설정된다.

액션 세그웨이

트리거(버튼 등)와 세그웨이가 직접 연결된 세그웨이
세그 연결 옵션 중에서 Persent Modaly는 present 메소드를 이용한 화면 전환과 같은 기능을 한다.
내비게이션 컨트롤러가 추가되어 있는 상태에서 Show 타입의 세그웨이를 생성하면 내비게이션 컨트롤러를 통한 화면 이동이 발생한다.
내비게이션 컨트롤러가 없을 때는 Show 타입으로 생성해도 Persent Modaly 방식으로 실행된다.
내비게이션 컨트롤러와 첫번째 뷰컨트롤러 사이의 연결도 세그웨이의 일종으로 관계형 세그웨이다.

이전 화면으로 돌아갈때는 Present Modaly 방식은 present 메소드와 같이 dismiss 메소드를 사용하고, Show 방식은 내비게이션 컨트롤러를 사용했을 때와 같이 popViewController 메소드를 사용한다.
또 다른 방법은 세그웨이 구조에서 제공하는 Unwind Segue를 이용하면 된다.
Unwind Segue는 프레젠테이션 방식이나 내비게이션 컨트롤러를 이용한 방식에 구분 없이 실행된다.

💡 Unwind Segue 사용 방법

스토리보드의 뷰컨트롤러 상단의 도크 바에 Exit 아이콘이 있다. 첫번째 뷰컨트롤러에 Unwind Segue 메소드를 만들고 (버튼과 연결할 필요 없고 만들어두기만 하면 된다) 두번째 뷰컨트롤러에서 이전 화면으로 이동할 트리거가 될 버튼에 Exit 아이콘을 연결하면 첫번째 뷰컨트롤러에 만들어둔 메소드를 인식하고, 연결하면 해당 메소드가 있는 뷰컨트롤러로 이동할 수 있다.

화면이 여러개일 때도 동일하게 이동할 뷰컨트롤러에 Unwind 메소드를 만들고 연결해주면 된다. 내비게이션 컨트롤러를 사용했다면 Page1 -> Page2 -> Page3로 이동했을 때 차례대로 스택에 쌓여있다가 Page3에서 1으로 간다면 Page2의 인스턴스도 메모리에서 자동으로 해제된다.

매뉴얼 세그웨이

뷰컨트롤러와 뷰컨트롤러 사이에 연결되어있는 수동 실행 세그웨이
액션 세그웨이는 트리거의 터치에 의해 실행되므로 별도의 처리 코드가 필요없지만, 매뉴얼 세그웨이는 소스코드에서 세그웨이를 실행할 메소드를 호출해야 한다. 스토리보드에서 뷰컨트롤러와 뷰컨트롤러끼리 세그웨이로 연결 후 이름을 정하고 사용한다.

performSegue(withIdentifier: <세그웨이 식별자>, sender: <세그웨이 실행 객체>)

커스텀 세그웨이

기본적인 기능의 세그웨이로는 원하는 기능을 구현하기 어려울때 UIStoryboardSegue 클래스를 서브클래싱하여 새로운 기능을 갖춘 세그웨이 객체를 정의할 수 있다.
화면 전환 시 뷰컨트롤러 전체를 전환하는 대신 다른 컨트롤러에 있는 뷰만 읽어와 전환하는 세그웨이다. 이를 이용하면 뷰컨트롤러 하나에서 상태값에 따라 여러가지 다른 뷰를 다양하게 표현하는 일이 가능하다. 하지만 이렇게 하면 하나의 뷰컨트롤러에 두개 이상의 루트 뷰를 제어하는 것이므로 좋은 구조가 아니라서 지양하는 방법이다.

UIView.transition(from: <출발지 뷰>,
	              to: <목적지 뷰>.
                  duration: <화면 전환에 소요되는 시간(초단위)>,
                  options: <애니메이션 전환 옵션>,
                  completion: <화면 전환이 끝난후 실행할 함수나 클로저 구문>)

전처리 메소드

세그웨이를 이용하여 화면을 전환하는 과정에서 뭔가 처리를 해주어야 할 때는 세그웨이가 실행되기 전에 특정한 메소드를 호출하도록 설계되어있어서 이를 이용하면 필요한 처리를 해줄 수 있다. 이 메소드의 호출 주체는 개발자가 아니라 구현해놓으면 시스템이 필요한 시점에 자동으로 호출한다. UIViewController 클래스에 이미 정의되어있어서 필요 시에 오버라이드 해서 사용하는 것이다. 대부분 다음 화면으로 값을 전달하는데 사용된다.

prepare(for segue: UIStoryboardSegue, sender: Any?){...}

세그 사용 방법

0개의 댓글