You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.22 08:15:35