lufei's Studio.

iOS 关于UINavigationBarDelegate

字数统计: 503阅读时长: 2 min
2021/09/17 Share

UINavigationBarDelegate 的一个问题

为了能够在恰当的时候拦截所需要的控制器的返回事件,实现 UINavigationBarDelegate 是一个还不错的办法.

比如就像这位开发者写的这样:UIViewController-BackButtonHandler

因为我的项目大部分都是用的 swift,于是我就用 swift 简单实现了一下 UINavigationBarDelegate,直到昨天,在 iOS13 以下出现了难以置信的 bug,

具体的 bug 表现:在 iOS13 以上一切正常,在 iOS13 以下会导致系统的返回按钮失效。

真是个可怕的 bug。

解决问题

经过搜索,在这里 PopViewController strange behaviour 发现了解决问题的方法。

代码是 OC,大概如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
@interface UINavigationController () <UINavigationBarDelegate>
@end
@implementation CustomNavigationController
- (BOOL)navigationBar:(UINavigationBar *)navigationBar shouldPopItem:(UINavigationItem *)item
{
BOOL rv = TRUE;
if ([[CustomNavigationController superclass]
instancesRespondToSelector:@selector(navigationBar:shouldPopItem:)]) {
rv = [super navigationBar:navigationBar shouldPopItem:item];
}
return rv;
}
@end

新的问题

上面说过,我的项目主要使用 swift,而上文的解决方案用的是 OC,于是,我又得用 swift 改写一下,根据上面那位答主的介绍,可以知道,每一个 UINavigationViewController 应该都有一个隐藏实现的 navigationBar: shouldPopItem: 方法,只需要在子类的实现中调用它就可以了。

但是 swift 的编译器并不能接受你去调用一个隐藏实现的方法,即使你确定它一定是有并且实现了的,为什么我这么确定呢?因为改写之后,除了显而易见的报错之外,我还在 swift 的 bug 列表里找到了同样的问题。

SR-13788

这位朋友和我写出了一样的代码和一样的报错,苦笑~

最后

很无奈,我只能用 OC 实现了这个过程,并向外暴露了一个 custom 的 navigationBar: shouldPopItem: 方法供 swift 调用。

1
2
3
4
5
6
7
8
9
10
11
12
@interface UINavigationController () <UINavigationBarDelegate>
@end
@implementation CustomNavigationController
- (BOOL)custom_navigationBar:(UINavigationBar *)navigationBar shouldPopItem:(UINavigationItem *)item {
BOOL rv = TRUE;
if ([[CustomNavigationController superclass]
instancesRespondToSelector:@selector(navigationBar:shouldPopItem:)]) {
rv = [super navigationBar:navigationBar shouldPopItem:item];
}
return rv;
}
@end

测试下来,一切正常。

真是坑爹的一天啊!!!!

CATALOG
  1. 1. UINavigationBarDelegate 的一个问题
  2. 2. 解决问题
  3. 3. 新的问题
  4. 4. 最后