UINavigationController使用时,导航栏隐藏时出现空白黑色区域时,应该如何解决?
情况1:视图控制器A导航栏隐藏,视图控制器B导航栏显示,当 A push 到 B 时,再由 B pop 回到 A 时,会出现与导航栏等高的黑色区域。
情况2:视图控制器A导航栏隐藏,视图控制器B导航栏显示,当 A present 到 B 时,再由 B dismiss 回到 A 时,会出现与导航栏等高的黑色区域,且同时会伴有跳动情况。
首先需要明白的是,隐藏导航栏共有4种方法,使用方法3,且animated必须设置为YES,则可以避免出出空白黑色区域。
方法1
[self.navigationController.navigationBar setHidden:YES];
方法2
[self.navigationController setNavigationBarHidden:YES];
方法3 (结合视图控制器即将显示,即将隐藏的方法使用,可以有效解决情况1 的问题)
[self.navigationController setNavigationBarHidden:YES animated:YES];
除了解决黑色区域显示问题,还需要考虑到 A 显示时不会出现抖动的情况(即 A 视图显示时,先出现与状态栏等高的黑色区域,然后再向上移动),代码参考如下:
- (void)viewWillAppear:(BOOL)animated
{
[super viewWillAppear:animated];
// 1 B pop 回到 A 时,不会出现黑色区域,但可能会出现抖动情况
// [self.navigationController setNavigationBarHidden:YES animated:YES];
// 2 B pop 回到 A 时,会出现黑色区域,但不会出现抖动情况
// [self.navigationController setNavigationBarHidden:YES animated:NO];
// 3 B pop 回到 A 时,不会出现黑色区域,也不会出现抖动情况
[self.navigationController setNavigationBarHidden:YES animated:animated];
}
- (void)viewWillDisappear:(BOOL)animated
{
[super viewWillDisappear:animated];
[self.navigationController setNavigationBarHidden:NO animated:YES];
}
方法4(可以有效解决情况2 的问题)
// 设置代理 注意添加协议UINavigationControllerDelegate
self.navigationController.delegate = self;
#pragma mark UINavigationControllerDelegate
- (void)navigationController:(UINavigationController *)navigationController willShowViewController:(UIViewController *)viewController animated:(BOOL)animated
{
if ([viewController isEqual:self])
{
[self.navigationController setNavigationBarHidden:YES animated:YES];
}
else
{
[self.navigationController setNavigationBarHidden:NO animated:YES];
}
}
使用方法4进行隐藏或显示导航栏视图控制器时,有可能出现另外一种情况,即由导航栏视图控制器A push后的另一个导航栏视图控制器B也是设置了导航栏控制器的隐藏或显示,再由B返回A时,可能会造成A的异常,造成这种情况的原因在于A的代理改变了,只需要重置一下就可以解决该问题。
- (void)viewWillAppear:(BOOL)animated
{
[super viewWillAppear:animated];
if (self.navigationController.delegate != self)
{
self.navigationController.delegate = self;
}
}
注意事项
1、使用非代理方法隐藏,或显示导航栏时,push出新的视图控制器时可能会出现导航栏大小的黑色区域,这时候需要添加动画效果,即设置为YES;同时该方法通常在视图控制器即将消失,或显示的方法中实现;
2、使用非代理方法隐藏,或显示导航栏时,present新的视图控制器时可能会出现导航栏大小的黑色区域,同时会出现跳动的情况,这时候应该使用代理方法来设置隐藏,或显示导航栏,同时屏蔽动画效果,即设置成NO。