Đọc tất cả các câu trả lời và không thể thấy giải pháp chính xác. Cách đúng để làm như vậy là tạo UIViewControllerAnimatedTransitioning tùy chỉnh cho đại biểu VC đã trình bày.
Vì vậy, nó giả định thực hiện nhiều bước hơn, nhưng kết quả là tùy chỉnh nhiều hơn và không có một số tác dụng phụ, như chuyển từ chế độ xem cùng với chế độ xem được trình bày.
Vì vậy, giả sử bạn có một số ViewController và có một phương pháp để trình bày
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
và dismissTransition
được sử dụng để tạo hiệu ứng cho bộ điều khiển chế độ xem của bạn. Vì vậy, bạn sử dụng ViewController của mình để UIViewControllerTransitioningDelegate
:
extension ViewController: UIViewControllerTransitioningDelegate {
func animationController(forPresented presented: UIViewController, presenting: UIViewController, source: UIViewController) -> UIViewControllerAnimatedTransitioning? {
return presentTransition
}
func animationController(forDismissed dismissed: UIViewController) -> UIViewControllerAnimatedTransitioning? {
return dismissTransition
}
}
Vì vậy, bước cuối cùng là tạo chuyển đổi tùy chỉnh của bạn:
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)
})
}
}
Trong bộ điều khiển chế độ xem mã đó được trình bày theo ngữ cảnh hiện tại, bạn có thể thực hiện các tùy chỉnh của mình từ thời điểm đó. Ngoài ra, bạn có thể thấy tùy chỉnh UIPresentationController
cũng hữu ích (chuyển vào sử dụng UIViewControllerTransitioningDelegate
)