[번역] UIPresentationController (애플 공식 문서)

삭제된 Velog·2024년 10월 12일

UIKit

목록 보기
15/21
post-thumbnail

본 글은 UIPresentationController (애플 공식 문서)를 한국어로 번역하여 옮긴 글입니다.

트랜지션 애니메이션과 뷰 컨트롤러의 프리젠테이션을 관리하는 객체

iOS 8.0+ | iPadOS 8.0+ | Mac Catalyst 13.1+ | tvOS 9.0+ | visionOS 1.0+

@MainActor
class UIPresentationController: NSObject

Overview

뷰 컨트롤러가 표시(present)되는 순간부터 사라지는 순간까지 UIKit은 뷰 컨트롤러의 프리젠테이션 과정의 다양한 측면을 관리하기 위해 프리젠테이션 컨트롤러를 사용합니다. 프리젠테이션 컨트롤러는 애니메이터 객체가 제공하는 것 외에도 자체적인 애니메이션을 추가할 수 있으며, 사이즈 변경에 대응할 수 있고, 뷰 컨트롤러가 화면에 표시되는 방식의 다른 측면도 관리할 수 있습니다.

present(_:animated:completion:) 메서드를 사용하여 뷰 컨트롤러를 표시할 때, UIKit은 항상 프리젠테이션 과정을 관리합니다. 이 과정의 일부는 주어진 프리젠테이션 스타일에 적합한 프리젠테이션 컨트롤러를 생성하는 것을 포함합니다. (UIModalPresentationStyle.pageSheet 스타일처럼) 내장된 스타일의 경우, UIKit은 필요로 하는 프리젠테이션 컨트롤러 객체를 정의하고 생성합니다. 사용자화된 프리젠테이션 컨트롤러를 제공할 수 있는 유일한 경우는 뷰 컨트롤러의 modalPresentationStyle 프로퍼티를 UIModalPresentationStyle.custom으로 설정할 때입니다. 표시되는 중인 뷰 컨트롤러 아래에 장식 뷰나 그림자 뷰를 추가하기를 원하거나 프리젠테이션 동작을 다른 방법으로 수정하기를 원한다면 사용자화된 프리젠테이션 컨트롤러를 제공할 수 있습니다.

사용자화된 프리젠테이션 컨트롤러 객체를 뷰 컨트롤러의 트랜지션 델리게이트를 통해 전달하세요. UIKit은 프리젠트된 뷰 컨트롤러가 화면에 보이는 동안 프리젠테이션 컨트롤러에 대한 참조를 유지합니다. 트랜지션 델리게이트와 그것이 제공하는 객체에 대한 자세한 정보는 UIViewControllerTransitioningDelegate를 참조하세요.

Understand the presentation process

프리젠테이션 컨트롤러에 의해 관리되는 프리젠테이션 과정은 3단계로 나누어질 수 있습니다.

  • 표시하기(presentation) 단계는 일련의 트랜지션 애니메이션을 통해 새로운 뷰 컨트롤러를 화면에 표시하는 과정을 포함합니다.

  • 관리(management) 단계는 새로운 뷰 컨트롤러가 화면에 보이는 동안 (기기 회전처럼) 환경 변화에 대응하는 과정을 포함합니다.

  • 사라지기(dismissal) 단계는 일련의 트랜지션 애니메이션을 통해 새로운 뷰 컨트롤러가 화면에 사라지게 하는 과정을 포함합니다.

이러한 모든 단계에서 프리젠테이션 컨트롤러의 역할은 자신의 고유한 사용자화 뷰와 상태 정보를 관리하는 것입니다. 표시하기사라지기 단계 중에는 프리젠테이션 컨트롤러는 자신의 사용자화 뷰를 뷰 계층 구조에 추가하고 이러한 뷰를 위한 적절한 트랜지션 애니메이션을 생성합니다. 화면에 보이는 뷰 컨트롤러의 뷰의 애니메이션은 여전히 UIViewControllerAnimatedTransioning 프로토콜을 채택하는 애니메이터 객체가 관리합니다. UIKit은 표시하기사라지기 단계의 시작과 끝에서 개별 프리젠테이션 컨트롤러의 메서드를 호출하여 프리젠테이션 컨트롤러가 필요로 하는 작업을 수행할 수 있습니다.

Add custom views to a presentation

UIPresentationController 클래스는 뷰 컨트롤러가 표시될 때 뷰 계층 구조를 조정하기 위한 특정 엔트리 포인트(entry point)를 정의합니다. 뷰 컨트롤러가 막 표시될 때, UIKit은 프리젠테이션 컨트롤러의 presentationTransitionWillBegin() 메서드를 호출합니다. 이 메서드를 사용하여 뷰 계층 구조에 뷰를 추가하거나 해당 뷰와 관련된 애니메이션을 설정할 수 있습니다. 표시하기 단계의 끝에서 UIKit은 트랜지션이 끝났음을 알리기 위해 presentationTransitionDidEnd(_:) 메서드를 호출합니다.

아래 예제는 사용자화 프리젠테이션 컨트롤러를 위한 presentationTransitionWillBegin()presentationTransitionDidEnd(:) 메서드의 샘플 구현을 보여줍니다. 아래 예제에서 표시되는 뷰 컨트롤러의 배경으로 어두워지는(dimming) 뷰를 추가합니다. (_dimmingView 변수는 개발자가 제공하는 사용자화 UIView입니다) 뷰 컨트롤러가 표시될 때, _presentationTransitionWillBegin() 메서드는 먼저 어두워지는 뷰를 추가하고 뷰 컨트롤러의 컨텐츠를 어두워지는 뷰 안에 포함시킵니다. 다른 트랜지션 애니메이션과 함께 실행될 페이드-인 애니메이션을 구성합니다. 사용자가 제스처를 통해 프리젠테이션 단계를 중지한다면, presentationTransitionDidEnd(:)_ 메서드는 어두워지는 뷰를 제거합니다. 프리젠테이션에 성공하면, 어두워지는 뷰와 표시되는 뷰 컨트롤러 모두 사라지기 전까지 화면에 남아있습니다.

- (void)presentationTransitionWillBegin {
   // Add a custom dimming view behind the presented view controller's view.
   [[self containerView] addSubview:_dimmingView];
   [_dimmingView addSubview:[[self presentedViewController] view]];
 
   // Use the transition coordinator to set up the animations.
    id <UIViewControllerTransitionCoordinator> transitionCoordinator =
          [[self presentingViewController] transitionCoordinator];
 
   // Fade in the dimming view during the transition.
    [_dimmingView setAlpha:0.0];
    [transitionCoordinator animateAlongsideTransition:
       ^(id<UIViewControllerTransitionCoordinatorContext> context) {
          [_dimmingView setAlpha:1.0];
       } completion:nil];
}
 
- (void)presentationTransitionDidEnd:(BOOL)completed {
   // Remove the dimming view if the presentation is terminated.
   if (!completed) {
      [_dimmingView removeFromSuperview];
   }
}

뷰 컨트롤러가 사라질 때, 애니메이션 구성을 위해 dismissalTransitionWillBegin() 메서드를 사용하고 뷰 계층 구조에서 사용자화 뷰를 제거하기 위해 dismissalTransitionDidEnd(_:) 메서드를 사용하세요.

Adapt to size class changes

사이즈 클래스의 변화는 앱이 컨텐츠를 표시하는 방식을 대규모로 변경해야 한다는 신호입니다. 프리젠테이션 컨트롤러는 표시된 뷰 컨트롤러의 (필요하다면) 프리젠테이션 스타일을 조정하여 사이즈 클래스 변화를 관리합니다. 이러한 조정은 현재 프리젠테이션 스타일이 새로운 환경에 적합하지 않을 때만 이루어집니다. 예를 들어, 팝오버는 사이즈 클래스가 horizontally regular에서 horizontally compact로 변하면 풀-스크린 표시가 됩니다. 풀-스크린 프리젠테이션 스타일처럼 새로운 환경에 이미 적합한 프리젠테이션 스타일은 아무런 변경이 이루어지지 않습니다.

표시된 뷰 컨트롤러의 사이즈 클래스가 horizontally regular에서 horizontally compact로 변화하면, 프리젠테이션 컨트롤러는 adaptivePresentationStlye 메서드를 호출하여 어느 새로운 스타일을 적용할지 결정합니다. 새로운 스타일이 필요하다면, 프리젠테이션 컨트롤러는 새로운 스타일로 전환을 시작하며, 프리젠테이션 컨트롤러 객체가 새로운 객체로 교체될 수 있습니다. 프리젠테이션 컨트롤러는 변경될 수 있기에, 항상 표시된 뷰 컨트롤러의 presentationController 프로퍼티에서 프리젠테이션 컨트롤러를 가져와야 합니다.

프리젠테이션 스타일이 변화하면, 프리젠테이션 컨트롤러는 새로운 표시된 뷰 컨트롤러를 특정할 수 있도록 기회를 제공합니다. 전환이 시작되기 전에, 프리젠테이션 컨트롤러는 델리게이트 객체의 presentationController(_:viewControllerForAdaptivePresentationStyle:) 메서드를 호출합니다. 이 메서드를 구현하면, 표시된 컨텐츠에 대해 크고 작은 조정을 할 수 있습니다. 큰 조정으로는 현재 뷰 컨트롤러를 주어진 사이즈 클래스에 맞게 디자인된 새로운 뷰 컨트롤러로 교체가 될 수 있습니다. 작은 조정으로는 새로운 사이즈 클래스에서 네비게이션을 용이하게 하기 위해 현재 뷰 컨트롤러를 네비게이션 컨트롤러 안에 넣을 수 있습니다.

Respond to size changes

크기 변화는 뷰 컨트롤러의 뷰의 너비와 높이에 대한 작은 변화를 의미합니다. 일반적으로, 이러한 변화는 기기가 포트레잇(portrait)에서 랜드 스케이프(landscape)로 회전하면 발생합니다. 크기 변화가 발생하면, UIKit은 프리젠테이션 컨트롤러의 viewWillTransition(to:with:) 메서드를 호출합니다. 사용자화 프리젠테이션에서는 해당 메서드를 사용하여 프리젠테이션 컨트롤러의 사용자화 뷰를 수정하거나 뷰 계층 구조에 변화를 주어야 합니다. 예를 들어, 새로운 크기에 더 잘 맞는 사용자화 장식 뷰로 교체할 수 있습니다.

크기 변경이 임박했음을 프리젠테이션 컨트롤러에 알리고 난 후, UIKit은 통상적인 레이아웃 프로세스를 시작합니다. 오토 레이아웃을 사용하는 앱은 오토 레이아웃 메커니즘이 필요하다면 뷰 크기를 조절하기에 어느 것도 할 필요가 없습니다. 그러나 사용자화 프리젠테이션 컨트롤러가 특정 레이아웃에 변화를 주어야 한다면, containerViewWillLayoutSubviews()containerViewDidLayoutSybviews() 메서드에서 할 수 있습니다. 이 메서드는 UIViewControllerviewWillLayoutSubviews()viewDidLayoutSubviews() 메서드와 동일하며, 같은 방식으로 쓰입니다. UIKit은 뷰 계층 구조에 있는 뷰들의 layoutSubviews() 메서드가 호출되기 전과 후에 해당 메서드를 호출합니다.

Subclassing notes

사용자화 프리젠테이션 스타일의 경우, UIPresentationController를 서브클래싱하고, 사용자화 프리젠테이션 동작을 구현하기 위해 적어도 일부 메서드를 재정의해야 합니다. 프리젠테이션 프로세스를 사용자화하기 위해 사용자화 프리젠테이션 컨트롤러를 사용하세요.

사용자화 프리젠테이션 컨트롤러에서 무조건 init(presentedViewController:presenting:) 이니셜라이저를 호출해야 합니다. 이 메서드는 클래스의 지정 이니셜라이저(desinated initalizer)입니다. UIKit은 모든 프리젠테이션 컨트롤러 객체에서 필요한 초기화 작업을 수행하기 위해 해당 메서드를 사용합니다.

Methods to override

UIPresentationController 서브클래스가 하나 이상의 사용자화 뷰를 관리한다면, 아래 메서드를 재정의하는 것을 고려하세요.

서브클래스는 사용자화 동작 제공을 필요로 하면 해당 클래스의 다른 메서드를 재정의할 수 있습니다. 예를 들어, shouldPresentInFullscreen이나 frameOfPresentedViewInContainerView 메서드를 재정의하고, 기본 구현으로 제공하는 값과 다른 값을 반환할 수 있습니다.

profile
rlarjsdn3.github.io

0개의 댓글