iOS自定义转场动画报错:无法将SlideAnimation.Type赋值给UIViewControllerTransitioningDelegate?
解决iOS自定义转场的类型赋值错误
这个错误的核心原因很明确:你把SlideAnimation类本身直接赋值给了需要实例对象的transitioningDelegate属性。
错误根源
destination.transitioningDelegate要求的是一个遵守UIViewControllerTransitioningDelegate协议的对象实例,而你写的destination.transitioningDelegate = SlideAnimation是把类的类型(SlideAnimation.Type)传了进去,类型完全不匹配,所以才会报这个赋值错误。
修复步骤及完整代码示例
1. 补全SlideAnimation的协议实现
首先确保你的SlideAnimation完整实现了转场相关的协议,不仅要遵守UIViewControllerTransitioningDelegate,通常还需要实现UIViewControllerAnimatedTransitioning来提供具体的动画逻辑:
import UIKit class SlideAnimation: NSObject, UIViewControllerTransitioningDelegate, UIViewControllerAnimatedTransitioning { // 提供present转场的动画控制器 func animationController(forPresented presented: UIViewController, presenting: UIViewController, source: UIViewController) -> UIViewControllerAnimatedTransitioning? { return self } // 提供dismiss转场的动画控制器 func animationController(forDismissed dismissed: UIViewController) -> UIViewControllerAnimatedTransitioning? { return self } // 转场动画时长 func transitionDuration(using transitionContext: UIViewControllerContextTransitioning?) -> TimeInterval { return 0.3 } // 自定义转场动画逻辑(示例:从左侧滑入) func animateTransition(using transitionContext: UIViewControllerContextTransitioning) { guard let toViewController = transitionContext.viewController(forKey: .to), let fromViewController = transitionContext.viewController(forKey: .from) else { transitionContext.completeTransition(false) return } let containerView = transitionContext.containerView // 设置目标VC的初始位置(屏幕左侧外) toViewController.view.frame = CGRect(x: -containerView.bounds.width, y: 0, width: containerView.bounds.width, height: containerView.bounds.height) containerView.addSubview(toViewController.view) // 执行滑入动画 UIView.animate(withDuration: transitionDuration(using: transitionContext), delay: 0, options: .curveEaseInOut, animations: { toViewController.view.frame = containerView.bounds fromViewController.view.alpha = 0.8 // 可选:给原VC加个透明度变化 }, completion: { finished in fromViewController.view.alpha = 1.0 transitionContext.completeTransition(finished && !transitionContext.transitionWasCancelled) }) } }
2. 修改ViewController中的赋值逻辑
把类名改成实例化对象,同时记得设置目标VC的modalPresentationStyle(否则系统默认的卡片转场会覆盖自定义逻辑):
import UIKit class ViewController: UIViewController{ override func prepare(for segue: UIStoryboardSegue, sender: Any?) { let destination = segue.destination // 创建SlideAnimation的实例,而不是直接用类名 destination.transitioningDelegate = SlideAnimation() // 必须设置这个属性,否则自定义转场不会生效 destination.modalPresentationStyle = .fullScreen } }
额外注意点
- 如果你的转场是dismiss操作,记得在目标VC中也保持
transitioningDelegate的引用(或者把动画实例设为控制器属性),否则可能因为实例被提前释放导致动画异常。 - 可以根据需求修改
animateTransition里的动画逻辑,比如改成从右侧滑入、缩放等效果。
内容的提问来源于stack exchange,提问作者Laurcode
相关产品推荐
相关产品推荐

