iOS에서 뷰 컨트롤러 전환(Modal, Present/Dismiss)을 커스텀 애니메이션으로 제어하려면
UIViewControllerTransitioningDelegate 프로토콜을 사용한다.
UIViewControllerTransitioningDelegate는 전환 과정에서 사용할 객체(애니메이터, 인터랙션 컨트롤러 등)를 반환한다.protocol UIViewControllerTransitioningDelegate : AnyObject {
func animationController(forPresented presented: UIViewController,
presenting: UIViewController,
source: UIViewController) -> UIViewControllerAnimatedTransitioning?
func animationController(forDismissed dismissed: UIViewController)
-> UIViewControllerAnimatedTransitioning?
func interactionControllerForPresentation(using animator: UIViewControllerAnimatedTransitioning)
-> UIViewControllerInteractiveTransitioning?
func interactionControllerForDismissal(using animator: UIViewControllerAnimatedTransitioning)
-> UIViewControllerInteractiveTransitioning?
}
UIViewControllerAnimatedTransitioning는 실제 애니메이션 동작을 정의하는 프로토콜이다.
class CustomAnimator: NSObject, UIViewControllerAnimatedTransitioning {
let duration = 0.3
func transitionDuration(using transitionContext: UIViewControllerContextTransitioning?) -> TimeInterval {
return duration
}
func animateTransition(using transitionContext: UIViewControllerContextTransitioning) {
guard let toView = transitionContext.view(forKey: .to) else { return }
let container = transitionContext.containerView
// 초기 상태 (아래에서 시작)
toView.transform = CGAffineTransform(translationX: 0, y: container.bounds.height)
container.addSubview(toView)
// 애니메이션
UIView.animate(withDuration: duration, animations: {
toView.transform = .identity
}, completion: { finished in
transitionContext.completeTransition(finished)
})
}
}
class CustomTransitioningDelegate: NSObject, UIViewControllerTransitioningDelegate {
let animator = CustomAnimator()
func animationController(forPresented presented: UIViewController,
presenting: UIViewController,
source: UIViewController) -> UIViewControllerAnimatedTransitioning? {
return animator
}
func animationController(forDismissed dismissed: UIViewController) -> UIViewControllerAnimatedTransitioning? {
return animator
}
}
let vc = DetailViewController()
let customDelegate = CustomTransitioningDelegate()
vc.modalPresentationStyle = .custom
vc.transitioningDelegate = customDelegate
present(vc, animated: true, completion: nil)
modalPresentationStyle = .custom을 반드시 지정해야 한다.transitioningDelegate에 커스텀 델리게이트를 할당해야 커스텀 전환이 적용된다.UIViewControllerTransitioningDelegate는 애니메이션/인터랙션 객체를 연결하는 다리 역할이다.UIViewControllerAnimatedTransitioning이 담당한다.UIPercentDrivenInteractiveTransition 등을 활용한다.modalPresentationStyle = .custom과 transitioningDelegate 설정이 필요하다.