在项目中使用 WYPopover 时 UINavigationControllerDelegate 方法调用崩溃

UINavigationControllerDelegate method call crash when WYPopover used in project

我正在开发一款包含 WYPopoverController 的应用程序,它在应有的位置上运行良好。我想在两个控制器之间添加自定义动画,而不是内置 push / pop。

在包含 FROM 和 TO 控制器的导航控制器中,我不做任何与 WYPopoverController 相关的事情,在 FROM 和 TO 控制器中也不做。

我已经实现了导航控制器委托,非常简单和处理实际动画的动画师 class。

public class NavigationControllerDelegate: NSObject, UINavigationControllerDelegate {

let animator = Animator()

public func navigationController(navigationController: UINavigationController, animationControllerForOperation operation: UINavigationControllerOperation, fromViewController fromVC: UIViewController, toViewController toVC: UIViewController) -> UIViewControllerAnimatedTransitioning? {

    if operation == UINavigationControllerOperation.Pop {
        return self.animator
    }

    return nil
}
}

动画师class:

class Animator: NSObject, UIViewControllerAnimatedTransitioning {

public func transitionDuration(transitionContext: UIViewControllerContextTransitioning) -> NSTimeInterval {
    return 0.33
}

public func animateTransition(transitionContext: UIViewControllerContextTransitioning) {
    let toVC = transitionContext.viewControllerForKey(UITransitionContextToViewControllerKey)!
    let fromVC = transitionContext.viewControllerForKey(UITransitionContextFromViewControllerKey)!

    transitionContext.containerView().addSubview(toVC.view)
    toVC.view.alpha = 0

    UIView.animateWithDuration(self.transitionDuration(transitionContext), animations: { () -> Void in
        fromVC.view.transform = CGAffineTransformMakeScale(0.1, 0.1)
        toVC.view.alpha = 1
    }) { (finished) -> Void in
        fromVC.view.transform = CGAffineTransformIdentity
        transitionContext.completeTransition(!transitionContext.transitionWasCancelled())
    }
}  
}

在 FROM 控制器中我初始化导航委托

override public func viewDidLoad() {
    super.viewDidLoad()
    // ... some other code here
    self.navigationController?.delegate = NavigationControllerDelegate()
}

一切都会编译并运行,直到我点击(收集)单元格并想移至 TO 控制器。那时应用程序崩溃并出现错误: -[CALayer navigationController:animationControllerForOperation:fromViewController:toViewController:]: 无法识别的选择器发送到实例 0x7fc72e53e970

我添加了一个断点,我最终进入了 UINavigationController 的 sizzled_pushViewController:animated: 方法。老实说,我不知道如何解决这个问题。

WYPopoverController 正在使用 Method Swizzling 为 UINavigationController

调配 pushViewController:animated

所以基本上,当您看到 [self sizzled_pushViewController:aViewController animated:aAnimated]; 选择器在那里被调用时,这意味着您的 pushViewController:animated 选择器实际上被调用了,因为该方法已被调配。

现在关于您的崩溃,似乎不是选择器 navigationController:animationControllerForOperation:fromViewController:toViewController: 被发送到 UINavigationController,而是被发送到 CALayer,这当然不是对此作出回应,应用程序崩溃。

为什么会这样,我无法从我在这里看到的内容中猜出,但我所说的,希望能让你走上正确的轨道

事实证明,解决方案与 WYPopoverController 无关。显然 从其根控制器中设置导航控制器委托不是它应该完成的方式 。我设法重构我的代码以摆脱上述库,但它仍然因同样的异常而崩溃。

-[CALayer navigationController:animationControllerForOperation:fromViewController:toViewController:]: unrecognized selector sent to instance 0x7fc72e53e970

那时我真的很困惑。经过更多的挖掘和拉头发,我得到了可行的解决方案。 我在情节提要中初始化了导航控制器委托,所有部分都放在了正确的位置。