自定义转场动画中UIViewControllerContextTransitioning无法获取正确VC求助
首先,你遇到的核心问题是:在present动画的transitionContext中,from对应的视图控制器并不是你预期的NavigationGalleryViewController,而是它的容器控制器(大概率是UINavigationController)。
当你调用present(_:animated:completion:)时,transitionContext.viewController(forKey: .from)返回的是当前正在屏幕上、发起present操作的那个视图控制器。如果你的NavigationGalleryViewController是被嵌入在UINavigationController里面的,那么发起present的其实是这个导航控制器,而不是NavigationGalleryViewController本身——这就导致你强制类型转换失败,进入了guard的else分支。
解决办法
方法1:从导航控制器中获取目标VC
修改你的animateTransition方法里的guard语句,先判断是否为导航控制器,再取出它的顶层VC:
func animateTransition(using transitionContext: UIViewControllerContextTransitioning) { guard let toView = transitionContext.view(forKey: .to), // 先拿到发起present的导航控制器 let fromNavVC = transitionContext.viewController(forKey: .from) as? UINavigationController, // 从导航控制器中取出你的GalleryVC let fromVC = fromNavVC.topViewController as? NavigationGalleryViewController, let fromView = fromVC.collectionView?.cellForItem(at: indexPath) as? InstallationViewCell else { transitionContext.completeTransition(true) return } // 继续你的动画逻辑 }
方法2:确保发起present的是GalleryVC本身
检查你的视图控制器层级,确认调用present(gallery, ...)的是NavigationGalleryViewController实例,而不是它的导航控制器。如果之前是通过导航控制器发起的present,改成直接让NavigationGalleryViewController来执行present操作。
额外排查小技巧
你可以在guard语句前加个打印,确认from控制器的实际类型,方便定位问题:
let rawFromVC = transitionContext.viewController(forKey: .from) print("实际的From VC类型:\(type(of: rawFromVC))")
另外还要确保你的indexPath在动画执行时是有效的,避免因为cell不存在导致的转换失败。
内容的提问来源于stack exchange,提问作者Sacha.R

