在项目中使用 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
那时我真的很困惑。经过更多的挖掘和拉头发,我得到了可行的解决方案。 我在情节提要中初始化了导航控制器委托,所有部分都放在了正确的位置。
我正在开发一款包含 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
那时我真的很困惑。经过更多的挖掘和拉头发,我得到了可行的解决方案。 我在情节提要中初始化了导航控制器委托,所有部分都放在了正确的位置。