关于 UINavigationController 返回时,UI
2019-07-24 本文已影响42人
健了个平_24
该问题的讨论来自:https://github.com/ChenYilong/CYLTabBarController/issues/312
这个问题是苹果系统的问题,只要 UITabBar 是磨砂的,并且 push viewController 时 hidesBottomBarWhenPushed = YES 则手势返回的时候就会触发。
目前网上大部分的解决方法是在 AppDelegate 的 -application:didFinishLaunchingWithOptions:
方法里面对全局 TabBar 的 translucent 属性设置为 NO:
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
[[UITabBar appearance] setTranslucent:NO];
return YES;
}
虽然这方法的确奏效,但不知道为什么个所以然(估计都是复制粘贴的吧),而且这样设置之后 TabBar 就变得没有高斯模糊的效果了,所以这种做法是不靠谱的。
幸好搜到了这个问题的讨论链接,里面的ChenYilong大神解释道:
- 这个问题是 iOS 12.1 Beta 2 的问题,只要 UITabBar 是磨砂的,并且 push viewController 时 hidesBottomBarWhenPushed = YES 则手势返回的时候就会触发。
- 出现这个现象的直接原因是 tabBar 内的按钮 UITabBarButton 被设置了错误的 frame,frame.size 变为 (0, 0) 导致的。
并且给出了完美的解决方案:
写个 UITabBar 的分类,利用 runtime 进行判定
#import "UITabBar+JPExtensionn.h"
#import <objc/runtime.h>
@implementation UITabBar (JPExtensionn)
CG_INLINE BOOL
OverrideImplementation(Class targetClass, SEL targetSelector, id (^implementationBlock)(Class originClass, SEL originCMD, IMP originIMP)) {
Method originMethod = class_getInstanceMethod(targetClass, targetSelector);
if (!originMethod) {
return NO;
}
IMP originIMP = method_getImplementation(originMethod);
method_setImplementation(originMethod, imp_implementationWithBlock(implementationBlock(targetClass, targetSelector, originIMP)));
return YES;
}
+ (void)load {
/**
* 参考:https://github.com/ChenYilong/CYLTabBarController/issues/312
* 这个问题是 iOS 12.1 Beta 2 的问题,只要 UITabBar 是磨砂的,并且 push viewController 时 hidesBottomBarWhenPushed = YES 则手势返回的时候就会触发。
* 出现这个现象的直接原因是 tabBar 内的按钮 UITabBarButton 被设置了错误的 frame,frame.size 变为 (0, 0) 导致的。如果12.1正式版Apple修复了这个bug可以移除调这段代码(来源于QMUIKit的处理方式)
*/
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
if (@available(iOS 12.1, *)) {
OverrideImplementation(NSClassFromString(@"UITabBarButton"), @selector(setFrame:), ^id(__unsafe_unretained Class originClass, SEL originCMD, IMP originIMP) {
return ^(UIView *selfObject, CGRect firstArgv) {
if ([selfObject isKindOfClass:originClass]) {
// 如果发现即将要设置一个 size 为空的 frame,则屏蔽掉本次设置
if (!CGRectIsEmpty(selfObject.frame) && CGRectIsEmpty(firstArgv)) {
return;
}
}
// call super
void (*originSelectorIMP)(id, SEL, CGRect);
originSelectorIMP = (void (*)(id, SEL, CGRect))originIMP;
originSelectorIMP(selfObject, originCMD, firstArgv);
};
});
}
});
}
@end
看来是苹果系统的Bug呢!然而最新的手机版本还是会有该问题
ChenYilong大神说这是 iOS 12.1 Beta 2 的问题,听说现在已经修复了?但在 iOS 12.3.1 的正式版中,我自定义了一个pop动画,并且在里面用到了 tabBar ,却发现依然会有该问题...
使用分类后: 图标跟标题位置正常了
所以,这个问题苹果还没有完全解决。