转场动画
问题
iOS 自定义转场动画的实现方式?
答案
UIKit 自定义转场
// 1. 实现 UIViewControllerAnimatedTransitioning
class FadeTransition: NSObject, UIViewControllerAnimatedTransitioning {
func transitionDuration(using context: UIViewControllerContextTransitionContext?) -> TimeInterval {
return 0.3
}
func animateTransition(using context: UIViewControllerContextTransitionContext) {
guard let toView = context.view(forKey: .to) else { return }
let container = context.containerView
toView.alpha = 0
container.addSubview(toView)
UIView.animate(withDuration: 0.3) {
toView.alpha = 1
} completion: { _ in
context.completeTransition(!context.transitionWasCancelled)
}
}
}
// 2. 设置代理
class ViewController: UIViewController, UIViewControllerTransitioningDelegate {
func presentDetail() {
let vc = DetailVC()
vc.modalPresentationStyle = .custom
vc.transitioningDelegate = self
present(vc, animated: true)
}
func animationController(forPresented presented: UIViewController,
presenting: UIViewController,
source: UIViewController) -> UIViewControllerAnimatedTransitioning? {
return FadeTransition()
}
}
SwiftUI 转场
struct ContentView: View {
@State private var showDetail = false
var body: some View {
VStack {
if showDetail {
DetailView()
.transition(.asymmetric(
insertion: .scale.combined(with: .opacity),
removal: .slide
))
}
}
.animation(.spring(), value: showDetail)
}
}
// iOS 18+ matchedTransitionSource
// 共享元素转场
常见面试问题
Q1: 交互式转场怎么实现?
答案:使用 UIPercentDrivenInteractiveTransition,配合 UIPanGestureRecognizer,根据手势进度调用 update(_:)、finish()、cancel() 控制转场进度。iOS 侧滑返回就是这个原理。