【问题标题】:UINavigationControllerDelegate method call crash when WYPopover used in project项目中使用 WYPopover 时 UINavigationControllerDelegate 方法调用崩溃
【发布时间】:2015-05-22 07:14:00
【问题描述】:

我正在开发一个包含 WYPopoverController 的应用程序,它在应有的地方运行良好。我想在两个控制器之间添加自定义动画,而不是内置推送/弹出。

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

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

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 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: 方法。老实说,我不知道如何处理这个问题。

【问题讨论】:

    标签: ios swift animation method-swizzling


    【解决方案1】:

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

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

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

    【讨论】:

    • 同样的错误。事实上,问题在于导航委托。看起来在某个时刻WYPopoverController 触发了该方法并引用了委托。在我的例子中,我为委托设置了一个控制器,一旦它被释放,委托仍然保留引用。
    【解决方案2】:

    WYPopoverController 正在使用方法调配来调配pushViewController:animatedUINavigationController

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

    现在关于您的崩溃,似乎选择器navigationController:animationControllerForOperation:fromViewController:toViewController: 没有发送到UINavigationController,而是发送到CALayer,这当然不会响应并且应用程序崩溃。

    为什么会这样

    【讨论】:

    • 是的,我知道 ;) 在这里和 GitHub 上发布之前我已经完成了作业。我不知道为什么当委托设置为我的类的对象时它会调用 CALayer...
    猜你喜欢
    • 1970-01-01
    • 2019-11-20
    • 2017-10-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-01-26
    • 1970-01-01
    相关资源
    最近更新 更多