모든 답변을 읽고 올바른 해결책을 찾을 수 없습니다. 이를 수행하는 올바른 방법은 제시된 VC 델리게이트에 대해 사용자 정의 UIViewControllerAnimatedTransitioning을 만드는 것입니다.
따라서 더 많은 단계를 수행한다고 가정하지만 결과는 더 사용자 정의가 가능하며 제시된 뷰와 함께 뷰에서 이동하는 것과 같은 부작용이 없습니다.
따라서 일부 ViewController가 있고 프레젠테이션 방법이 있다고 가정합니다.
var presentTransition: UIViewControllerAnimatedTransitioning?
var dismissTransition: UIViewControllerAnimatedTransitioning?
func showSettings(animated: Bool) {
let vc = ... create new vc to present
presentTransition = RightToLeftTransition()
dismissTransition = LeftToRightTransition()
vc.modalPresentationStyle = .custom
vc.transitioningDelegate = self
present(vc, animated: true, completion: { [weak self] in
self?.presentTransition = nil
})
}
presentTransition
그리고 dismissTransition
뷰 컨트롤러를 애니메이션에 사용됩니다. 따라서 ViewController를 UIViewControllerTransitioningDelegate
다음과 같이 채택합니다 .
extension ViewController: UIViewControllerTransitioningDelegate {
func animationController(forPresented presented: UIViewController, presenting: UIViewController, source: UIViewController) -> UIViewControllerAnimatedTransitioning? {
return presentTransition
}
func animationController(forDismissed dismissed: UIViewController) -> UIViewControllerAnimatedTransitioning? {
return dismissTransition
}
}
따라서 마지막 단계는 사용자 지정 전환을 만드는 것입니다.
class RightToLeftTransition: NSObject, UIViewControllerAnimatedTransitioning {
let duration: TimeInterval = 0.25
func transitionDuration(using transitionContext: UIViewControllerContextTransitioning?) -> TimeInterval {
return duration
}
func animateTransition(using transitionContext: UIViewControllerContextTransitioning) {
let container = transitionContext.containerView
let toView = transitionContext.view(forKey: .to)!
container.addSubview(toView)
toView.frame.origin = CGPoint(x: toView.frame.width, y: 0)
UIView.animate(withDuration: duration, delay: 0, options: .curveEaseOut, animations: {
toView.frame.origin = CGPoint(x: 0, y: 0)
}, completion: { _ in
transitionContext.completeTransition(true)
})
}
}
class LeftToRightTransition: NSObject, UIViewControllerAnimatedTransitioning {
let duration: TimeInterval = 0.25
func transitionDuration(using transitionContext: UIViewControllerContextTransitioning?) -> TimeInterval {
return duration
}
func animateTransition(using transitionContext: UIViewControllerContextTransitioning) {
let container = transitionContext.containerView
let fromView = transitionContext.view(forKey: .from)!
container.addSubview(fromView)
fromView.frame.origin = .zero
UIView.animate(withDuration: duration, delay: 0, options: .curveEaseIn, animations: {
fromView.frame.origin = CGPoint(x: fromView.frame.width, y: 0)
}, completion: { _ in
fromView.removeFromSuperview()
transitionContext.completeTransition(true)
})
}
}
해당 코드보기 컨트롤러가 현재 컨텍스트에 표시되면 해당 지점에서 사용자 지정을 수행 할 수 있습니다. 또한 사용자 정의 UIPresentationController
도 유용하다는 것을 알 수 있습니다 (사용하여 전달 UIViewControllerTransitioningDelegate
)