Breadcrumbs

Logo

Breadcrumbs

View My GitHub Profile

23 November 2019

iOS에서 세그를 통한 화면전환 정리

View Controller Programming Guide for iOS의 Using Segues 파트를 요약 정리 및 추가하였습니다.

creating-segues

Using Segues

세그는 스토리보드에서 두 뷰 컨트롤러간의 전환을 정의합니다. unwind 세그를 이용하여 뷰 컨트롤러를 닫을 수도(dismiss) 있습니다.

세그는 프로그램적으로 trigger하는 것이 아니고, 런타임에 UIKit이 뷰 컨트롤러에 연관된 세그를 로드하고 대응되는 요소(버튼, 테이블 뷰의 row 등)에 연결합니다. 유저가 이 요소와 상호작용하면, UIKit이 적절한 뷰 컨트롤러를 로드하고 앱에게 세그가 일어날 것임을 알리고, 화면 전환을 실행합니다. UIKit이 보낸 알림을 이용하여 새 뷰 컨트롤러에게 데이터를 보내거나, 세그가 실행되는 것을 막을 수 있습니다.

Creating a Segue Between View Controllers

스토리보드에서 control-드래그를 통해 쉽게 화면 전환을 구현할 수 있습니다. 드래그의 시작점은 뷰, 컨트롤, bar button item, gesture recognizer, table row등이어야 하고, 끝점은 다른 뷰 컨트롤러입니다.

마우스 버튼을 떼면, 두 뷰 컨트롤러들 사이의 관계를 선택해야 합니다. 가능한 한 adaptive 세그를 선택하세요. Adaptive 세그는 현재 상황에 맞춰 그들의 화면 전환 형태을 자동으로 조절합니다. 예를 들어, Show 세그의 형태는 presenting view controller에 따라서 변경됩니다. Nonadaptive 세그는 iOS 7에서도 동작해야 하는 앱들을 위해 제공된 것이며, adaptive segue를 지원하지 않습니다. adaptive segue들과 그것들이 앱에서 어떻게 동작하는지를 나열하면 다음과 같습니다.

Segue type Behavior
Show (Push) 타겟 뷰 컨트롤러의 show(_:sender:)메서드를 사용하여 새 컨텐츠를 디스플레이한다. 세그는 대부분의 뷰 컨트롤러들의 새 컨텐츠를 원래의 뷰 컨트롤러 위에 모달로 띄우게 된다. 어떤 뷰 컨트롤러들은 이 메서드를 특별히 오버라이드하여 다른 형태를 구현한다. 예를 들어 네비게이션 컨트롤러는 새 뷰 컨트롤러를 네비게이션 스택에 푸시한다.
Show Detail (Replace) 타겟 뷰 컨트롤러의 showDetailViewController(_:sender:)메서드를 사용하여 새 컨텐츠를 디스플레이한다. 이 세그는 UISplitViewController 안에 임베드 된 뷰 컨트롤러들과만 관계가 있다. 이 세그를 이용하면 스플릿 뷰 컨트롤러는 두 번째 child view controller(the detail controller)를 새 컨텐츠로 바꾼다. 다른 대부분의 뷰 컨트롤러들은 새 컨텐츠를 모달로 띄운다.
Present Modally 지정된 presentation과 transition style을 사용하여 뷰 컨트롤러를 모달로 띄운다. 적절한 presentation context를 정의한 뷰 컨트롤러가 실제 프레젠테이션을 담당한다.
Present as Popover horizontally regular인 환경에서, 뷰 컨트롤러는 popover로 나타난다. horizontally compact인 환경에서는 뷰 컨트롤러가 full screen 모달 프레젠테이션으로 디스플레이된다.
show(_:sender:)

primary context를 기반으로 뷰 컨트롤러를 present한다. 뷰 컨트롤러를 디스플레이하려는 필요성과, 실제 화면에 presenting하는 과정을 decouple시키려면 이 메서드를 사용하면 된다. 이 메서드를 이용하면 뷰 컨트롤러가 네비게이션 컨트롤러 안에 임베드되어 있는지, 스플릿 뷰 컨트롤러 안에 임베드되어 있는지를 알 필요가 없다. UISplitViewControllerUINavigationController는 둘다 UIViewController를 상속하고, 이 메서드를 오버라이드하기 때문에 그들의 설계에 따라서 presentation을 수행한다. 뷰 컨트롤러를 디스플레이하는 방법을 커스텀하려면 해당 뷰 컨트롤러의 이 메서드를 오버라이드하면 된다.
showDetailViewController(_:sender:)

secondary (또는 detail) context를 기반으로 뷰 컨트롤러를 present한다. regular인 환경에서, UISplitViewController 클래스는 뷰 컨트롤러를 디테일 뷰 컨트롤러로 설치하도록 이 메서드가 오버라이드되어있고, compact인 환경에서는 이 메서드가 show(_:sender:)를 호출하도록 구현되어있다.
present(_:animated:completion:)

뷰 컨트롤러를 모달 방식으로 띄운다. horizontally regular인 환경에서, 뷰 컨트롤러는 modalPresentationStyle프로퍼티에 지정된 스타일로 프레젠트 된다. horizontally compact인 환경에서, 뷰 컨트롤러는 디폴트로 full screen으로 프레젠트 된다. 어떤 객체의 이 메서드를 호출할 때, 그 객체는 항상 프레젠테이션을 담당하지 않을 수도 있다. 각각의 프레젠테이션 스타일은 각각 다른 규칙을 갖고 있다. 예를 들어 full screen 프레젠테이션은 반드시 전체 화면으로 자리잡고 있는 뷰 컨트롤러에 의해 수행되어야 한다. 현재의 뷰 컨트롤러가 요청을 충족시키지 못한다면, 요청을 뷰 계층의 위쪽에 있는 가장 가까운 부모에게 보내고, 요청을 받은 뷰 컨트롤러가 요청을 처리할 수도 있고 다시 위쪽 부모로 보낼 수도 있다.

뷰 컨트롤러를 디스플레이하기 전에, 이 메서드는 프레젠테이션 스타일을 기반으로 presented 뷰 컨트롤러의 사이즈를 조절한다. 대부분의 프레젠테이션 스타일에서, 결과 화면은 presented 뷰 컨트롤러의 modalTransitionStyle 프로퍼티에 지정된 전환 스타일을 이용하여 애니메이션으로 나타난다. current context 프레젠테이션에서는, 뷰가 현재 뷰 컨트롤러의 전환 스타일을 사용하여 화면에 애니메이션으로 나타날 수 있다. completion handler는 presented 뷰 컨트롤러의 viewDidAppear(_:)가 호출된 다음에 호출된다.

세그를 생성한 후에, 속성 인스펙터에서 identifier를 할당할 수 있습니다. 세그 진행 중, 이 identifier를 이용하여 어떤 세그가 트리거되었는지를 알 수 있으며, 이것은 한 뷰 컨트롤러가 다수의 세그를 지원할 때 유용합니다. 이 identifier는 세그가 실행될 때 뷰 컨트롤러에 배달되는 UIStoryboardSegue 객체에 포함되어 있습니다.

Modifying a Segue’s Behavior at Runtime

segue-process

세그가 트리거 됐을 때 어떤 일이 일어나는지 보여주는 그림입니다. 대부분의 일은 새로운 뷰 컨트롤러로의 화면 전환을 담당하는 presenting 뷰 컨트롤러에서 일어납니다. 새 뷰 컨트롤러의 설정은 새 뷰 컨트롤러를 직접 생성하고 프레젠팅하는 과정과 본질적으로는 같습니다. 세그는 스토리보드에서 설정되기 때문에, 세그와 연관된 두 뷰 컨트롤러는 같은 스토리보드에 있어야 합니다.

세그가 일어나는 동안, UIKit은 현재 뷰 컨트롤러의 다음 메서드들을 호출하여 세그 실행의 결과에 영향을 끼칠 수 있도록 도와줍니다.

shouldPerformSegue(withIdentifier:sender:)

지정된 identifier의 세그가 실행되는 것을 결정한다. identifier로 트리거된 세그가 어떤 세그인지 구분한다.
prepare(for:sender:)

뷰 컨트롤러에게 세그가 실행되기 직전임을 알린다. segue 매개변수를 통해 세그에 연관된 뷰 컨트롤러들에 대한 정보를 알 수 있다. 서브클래스에서 이 메서드를 오버라이드하여 새 뷰 컨트롤러가 디스플레이 되기 전 설정하는 데 사용한다. 세그 객체는 transition에 대한 정보와, 연관된 두 뷰 컨트롤러들에 대한 레퍼런스를 갖고 있다. segue와 sender 매개변수를 통해 어떤 소스로부터 세그가 트리거됐는지를 구분하여 로직을 구현할 수 있다.

Creating an Unwind Segue

Unwind 세그는 프레젠트 된 뷰 컨트롤러들을 dismiss할 수 있도록 해 줍니다. 프레젠트 된 뷰 컨트롤러 화면의 버튼 등 적절한 객체와 Exit 객체를 연결하여 unwind 세그를 생성할 수 있습니다. 유저가 이 객체와 상호작용하면, UIKit은 뷰 컨트롤러 계층을 탐색하여 unwind 세그를 수행하기 적절한 객체를 찾습니다. 그리고 unwind 세그의 타겟을 드러낼 때 까지 현재 뷰 컨트롤러와 그 중간의 뷰 컨트롤러들을 dismiss합니다.

먼저 unwind 세그가 끝난 뒤 나타나야 할 뷰 컨트롤러에 다음과 같이 unwind 액션 메서드를 정의합니다.

@IBAction func myUnwindAction(unwindSegue: UIStoryboardSegue)

스토리보드에서 unwind 세그를 시작시킬 버튼(또는 다른 객체)과 Exit 객체를 control-드래그로 연결하고, 위에서 정의한 액션 메서드를 선택합니다.

위 unwind 액션 메서드에서 앱에 적절한 일들을 수행하도록 구현하세요. 뷰 컨트롤러를 dismiss하는 일은 UIKit이 수행하므로 이 세그에 연관된 뷰 컨트롤러를 직접 dismiss할 필요는 없습니다. 대신, dismiss되는 뷰 컨트롤러에 접근하여 데이터를 회수하려면 세그 객체(unwindSegue 매개변수)를 사용하세요. 또한 unwind 세그가 끝나기 전 현재 뷰 컨트롤러를 업데이트하는 데도 이 메서드를 이용할 수 있습니다.

Initiating a Segue Programmatically

세그는 보통 스토리보드 파일에서 연결이 생성되었기 때문에 일어납니다. 하지만, destination 뷰 컨트롤러를 아직 모르기 때문에 스토리보드에서 세그를 생성할 수 없을 때도 있습니다. 이런 상황에서, 현재 뷰 컨트롤러의 performSegue(withIdentifier:sender:) 메서드를 이용하여 프로그램적으로 세그를 트리거할 수 있습니다.

Creating a Custom Segue

인터페이스 빌더에서 제공하는 세그들의 표준 전환 스타일 중 원하는 게 없다면, 커스텀 세그를 만들 수 있습니다.

The Life Cycle of a Segue

커스텀 세그가 어떻게 동작하는지를 이해하려면, 세그 객체의 라이프 사이클을 이해할 필요가 있습니다. 세그 객체는 UIStoryboardSegue 클래스나 그 서브클래스의 인스턴스입니다. 앱에서 절대 직접 세그 객체를 생성하지는 않습니다. UIKit이 세그가 트리거될 때 생성합니다. 다음은 동작 순서입니다.

  1. 프레젠트 될 뷰 컨트롤러가 생성되고 초기화됩니다.
  2. 세그 객체가 생성되고 그 객체의 init(identifier:source:destination:) 메서드가 호출됩니다. identifier는 인터페이스 빌더에서 세그를 구분하기 위해 지정한 string 입니다. 나머지 두 매개변수는 각각 전환되는 두 뷰 컨트롤러 객체입니다.
  3. presenting 뷰 컨트롤러의 prepare(for:sender:) 메서드가 호출됩니다.
  4. 세그 객체의 perform() 메서드가 호출됩니다. 이 메서드는 새 뷰 컨트롤러를 화면에 가져오기 위해 전환을 수행합니다.
  5. 세그 객체의 레퍼런스가 릴리즈 됩니다.

Implementing a Custom Segue

커스텀 세그를 구현하기 위해서는, UIStoryboardSegue를 서브클래싱하고, 다음의 메서드들을 구현하세요:

커스텀 세그의 추가적인 프로퍼티를 설정하려면, 인터페이스 빌더에서는 할 수 없으니 세그를 트리거하는 source 뷰 컨트롤러의 prepare(for:sender:) 메서드 안에서 설정하세요.

마무리

이상으로 세그를 통한 화면 전환에 대해 정리하였습니다.

tags: iOS - swift - UIKit