UIViewControllerContextTransitioning 不会给我一个 ViewController

Posted

技术标签:

【中文标题】UIViewControllerContextTransitioning 不会给我一个 ViewController【英文标题】:The UIViewControllerContextTransitioning won't give me a ViewController 【发布时间】:2018-01-12 13:28:23 【问题描述】:

我面临一个难以理解的问题,我有一个 CollectionViewController,我想制作一个自定义动画。 我的收藏是一个画廊,我想从收藏画廊切换。到全屏画廊。

所以我有 ControllerTransitionDelegate

extension NavigationGalleryViewController: UIViewControllerTransitioningDelegate 

func presentationController(forPresented presented: UIViewController, presenting: UIViewController?, source: UIViewController) -> UIPresentationController? 
    return DimmingPresentationController(presentedViewController: presented, presenting: presenting)


func animationController(forPresented presented: UIViewController, presenting: UIViewController, source: UIViewController) -> UIViewControllerAnimatedTransitioning? 
    guard let selectedCellFrame = self.collectionView?.cellForItem(at: IndexPath(item: index, section: 0))?.frame else  return nil 
    return PresentingAnimator(pageIndex: index, originFrame: selectedCellFrame)

我的 DimmingPresentationController

class DimmingPresentationController: UIPresentationController 

lazy var background = UIView(frame: .zero)

override var shouldRemovePresentersView: Bool 
    return false

override func presentationTransitionWillBegin() 
    setupBackground()
    // Grabing the coordinator responsible for the presentation so that the background can be animated at the same rate
    if let coordinator = presentedViewController.transitionCoordinator 
        coordinator.animate(alongsideTransition:  (_) in
            self.background.alpha = 1
        , completion: nil)
    

    private func setupBackground() 
    background.backgroundColor = UIColor.black
    background.autoresizingMask = [.flexibleWidth, .flexibleHeight]
    background.frame = containerView!.bounds
    containerView!.insertSubview(background, at: 0)
    background.alpha = 0



还有我的演示动画师

class PresentingAnimator: NSObject, UIViewControllerAnimatedTransitioning 

private let indexPath: IndexPath
private let originFrame: CGRect
private let duration: TimeInterval = 0.5

init(pageIndex: Int, originFrame: CGRect) 
    self.indexPath = IndexPath(item: pageIndex, section: 0)
    self.originFrame = originFrame
    super.init()


func transitionDuration(using transitionContext: UIViewControllerContextTransitioning?) -> TimeInterval 
    return duration


func animateTransition(using transitionContext: UIViewControllerContextTransitioning) 

    guard let toView = transitionContext.view(forKey: .to),
        let fromVC = transitionContext.viewController(forKey: .from) as? NavigationGalleryViewController, // The problem is here ! 
        let fromView = fromVC.collectionView?.cellForItem(at: indexPath) as? InstallationViewCell
        else 
            transitionContext.completeTransition(true)
            return
    

 // All the animation things
 

我的大问题是我的执行进入 else 内部,因为他无法从 transitionContext.viewController 中找到 FromVC。 这就是我如何称呼我的画廊

gallery = SwiftPhotoGallery(delegate: self, dataSource: self)

    // Gallery visual colours stuff
    gallery.modalPresentationStyle = .custom
    gallery.transitioningDelegate = self

    present(gallery, animated: true, completion:  () -> Void in
        self.gallery.currentPage = self.index
    )

这是我从 transitionContext 收到的:

为什么 transitionContext 不会给我正确的 VC ?

【问题讨论】:

您实际上从transitionContext.viewController(forKey: .from) 那里得到了什么样的东西? 我刚刚更新了那个图片! :) 【参考方案1】:

好吧,我检查并注意到transitionContext.viewController(forKey: .from) 是 NavigationController。

行内:let fromVC = transitionContext.viewController(forKey: .from) as? NavigationGalleryViewController 应该是 nil,因为它不是 NavigationGalleryViewController 而是 NavigationController。

如果你愿意,你可以这样:let fromVC = transitionContext.viewController(forKey: .from).childViewControllers.first as? NavigationGalleryViewController

【讨论】:

以上是关于UIViewControllerContextTransitioning 不会给我一个 ViewController的主要内容,如果未能解决你的问题,请参考以下文章