UIKit의 Custom Transition: 맞춤형 화면 전환 효과

작성일 :

UIKit의 Custom Transition: 맞춤형 화면 전환 효과

UIKit을 이용한 iOS 개발에서는 기본적으로 제공되는 여러 화면 전환 효과가 있지만, 경우에 따라 좀 더 맞춤화된 특별한 효과를 원할 때가 있습니다. 이 글에서는 Swift와 UIKit을 활용해 커스텀 화면 전환 효과를 구현하는 방법을 자세히 설명하겠습니다.

기본 개념 이해하기

UIKit에서 화면 전환(transition)을 커스터마이징 하기 위해서는 몇 가지 주요 개념과 객체를 이해해야 합니다. 여기서 중요한 클래스와 프로토콜은 UIViewControllerAnimatedTransitioning, UIViewControllerTransitioningDelegate, 그리고 UIViewControllerContextTransitioning 입니다.

UIViewControllerAnimatedTransitioning

이 프로토콜은 커스텀 애니메이션 객체를 정의할 때 사용됩니다. 화면 전환에 필요한 애니메이션의 구현체를 만들기 위해 animateTransition(using:)transitionDuration(using:) 메소드를 필수적으로 구현해야 합니다.

swift
class CustomAnimator: NSObject, UIViewControllerAnimatedTransitioning {
    func transitionDuration(using transitionContext: UIViewControllerContextTransitioning?) -> TimeInterval {
        return 0.5 // 애니메이션의 지속 시간
    }

    func animateTransition(using transitionContext: UIViewControllerContextTransitioning) {
        // 애니메이션 코드 구현
    }
}

UIViewControllerTransitioningDelegate

이 프로토콜은 화면 전환 관리자로서, 커스텀 전환을 시작하기 위해 필요합니다. 다양한 전환 방식 (예: 프레젠테이션, 해제 등)에 따라 다른 애니메이터 객체를 반환하는 메소드를 포함하고 있습니다.

swift
class CustomTransitioningDelegate: NSObject, UIViewControllerTransitioningDelegate {
    func animationController(forPresented presented: UIViewController, presenting: UIViewController, source: UIViewController) -> UIViewControllerAnimatedTransitioning? {
        return CustomAnimator()
    }

    func animationController(forDismissed dismissed: UIViewController) -> UIViewControllerAnimatedTransitioning? {
        return CustomAnimator()
    }
}

UIViewControllerContextTransitioning

이 객체는 화면 전환 중 컨텍스트 정보를 제공합니다. 전환 중에 포함될 fromViewtoView 등을 관리하며 애니메이션의 시작과 끝을 처리합니다.

swift
func animateTransition(using transitionContext: UIViewControllerContextTransitioning) {
    guard let fromView = transitionContext.view(forKey: .from),
          let toView = transitionContext.view(forKey: .to) else { return }

    let containerView = transitionContext.containerView
    containerView.addSubview(toView)

    // 초기 상태 설정
    toView.alpha = 0

    // 애니메이션 처리
    UIView.animate(withDuration: transitionDuration(using: transitionContext), animations: {
        toView.alpha = 1
    }, completion: { finished in
        transitionContext.completeTransition(finished)
    })
}

실전 예제

이제 위 개념들을 이용해 실제 커스텀 화면 전환을 구현해보겠습니다. 간단한 페이드 인/아웃 효과를 예제로 사용할 것입니다.

1. Animator 클래스 정의

먼저 UIViewControllerAnimatedTransitioning 프로토콜을 구현한 애니메이터 클래스를 만듭니다.

swift
class FadeAnimator: NSObject, UIViewControllerAnimatedTransitioning {
    func transitionDuration(using transitionContext: UIViewControllerContextTransitioning?) -> TimeInterval {
        return 0.5
    }

    func animateTransition(using transitionContext: UIViewControllerContextTransitioning) {
        guard let fromView = transitionContext.view(forKey: .from),
              let toView = transitionContext.view(forKey: .to) else { return }

        let containerView = transitionContext.containerView
        containerView.addSubview(toView)

        toView.alpha = 0

        UIView.animate(withDuration: transitionDuration(using: transitionContext), animations: {
            toView.alpha = 1
        }, completion: { finished in
            fromView.removeFromSuperview()
            transitionContext.completeTransition(finished)
        })
    }
}

2. TransitioningDelegate 클래스 정의

이제 애니메이션을 적용할 뷰 컨트롤러에 해당 델리게이트를 설정합니다.

swift
class FadeTransitioningDelegate: NSObject, UIViewControllerTransitioningDelegate {
    func animationController(forPresented presented: UIViewController, presenting: UIViewController, source: UIViewController) -> UIViewControllerAnimatedTransitioning? {
        return FadeAnimator()
    }

    func animationController(forDismissed dismissed: UIViewController) -> UIViewControllerAnimatedTransitioning? {
        return FadeAnimator()
    }
}

3. 뷰 컨트롤러 설정

마지막으로, 뷰 컨트롤러에서 해당 델리게이트를 설정하고 화면 전환을 수행합니다.

swift
class ViewController: UIViewController {
    let transitioningDelegate = FadeTransitioningDelegate()

    func presentNewViewController() {
        let newViewController = UIViewController()
        newViewController.modalPresentationStyle = .fullScreen
        newViewController.transitioningDelegate = transitioningDelegate
        present(newViewController, animated: true, completion: nil)
    }
}

결론

여기까지 UIKit과 Swift를 이용해 커스텀 화면 전환 효과를 구현하는 방법을 살펴보았습니다. UIViewControllerAnimatedTransitioning, UIViewControllerTransitioningDelegate, 그리고 UIViewControllerContextTransitioning의 역할과 구현 방법을 잘 이해하면 다양한 맞춤형 전환 효과를 만들어낼 수 있습니다. 화면 전환을 커스터마이징하여 사용자 경험을 더욱 풍부하게 만들 수 있는 기회를 놓치지 마세요.