从已呈现的ViewController推送控制器时导航栏不显示
解决导航栏隐藏后推送新控制器无法显示的问题
我通过UINavigationController以模态方式呈现了ViewController A,并隐藏了其导航栏。但推送ViewController B时,即使在B中设置self.navigationController?.setNavigationBarHidden(false, animated: false)也无法让导航栏显示,相关代码及背景信息如下:
呈现ViewController A的Objective-C代码
AppDelegate* delegate = [AppDelegate applicationDelegate]; UIStoryboard *story = [UIStoryboard storyboardWithName:STORYBOARD_MAIN bundle:nil]; SelectionViewController *tutorial = [story instantiateViewControllerWithIdentifier:@"SelectionViewController"]; tutorial.providesPresentationContextTransitionStyle = YES; tutorial.definesPresentationContext = YES; [tutorial setModalPresentationStyle:UIModalPresentationOverCurrentContext]; tutorial.delegate = self; UINavigationController* navController = [[UINavigationController alloc] initWithRootViewController:tutorial]; navController.modalPresentationStyle = UIModalPresentationFullScreen; [navController.navigationBar setHidden:YES]; navController.providesPresentationContextTransitionStyle = YES; navController.definesPresentationContext = YES; [navController setModalPresentationStyle:UIModalPresentationOverCurrentContext]; [delegate.tabBarController presentViewController:navController animated:YES completion:NULL];
推送ViewController B的代码(Objective-C调用Swift控制器)
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:@"AppDetail" bundle:nil]; DetailViewController *vc = [storyboard instantiateViewControllerWithIdentifier:@"DetailViewController"]; [self.navigationController pushViewController:vc animated:YES]; [[self navigationController] setNavigationBarHidden:NO];
补充信息
- ViewController A基于Objective-C编写,ViewController B基于Swift编写
- 两个控制器分别位于不同的Storyboard中
解决方法
1. 用导航控制器的官方方法管理导航栏状态
你当前直接修改navController.navigationBar.hidden属性,这会绕过UINavigationController的内部状态管理逻辑,导致后续推送控制器时状态无法同步更新。
将呈现导航控制器时的隐藏代码替换为:
// 替换 [navController.navigationBar setHidden:YES]; [navController setNavigationBarHidden:YES animated:NO];
2. 调整推送B时的导航栏设置时机
可以选择两种方式确保导航栏正确显示:
方式一:在A中推送前/后设置
调整推送代码的顺序,先设置导航栏显示再推送(或配合动画同步执行):
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:@"AppDetail" bundle:nil]; DetailViewController *vc = [storyboard instantiateViewControllerWithIdentifier:@"DetailViewController"]; // 先设置导航栏显示,再推送,保持动画一致 [self.navigationController setNavigationBarHidden:NO animated:YES]; [self.navigationController pushViewController:vc animated:YES];
方式二:在B的生命周期方法中设置
在B的Swift代码中,重写viewWillAppear方法强制显示导航栏:
override func viewWillAppear(_ animated: Bool) { super.viewWillAppear(animated) self.navigationController?.setNavigationBarHidden(false, animated: animated) }
如果需要返回A时重新隐藏导航栏,可以在viewWillDisappear中恢复:
override func viewWillDisappear(_ animated: Bool) { super.viewWillDisappear(animated) self.navigationController?.setNavigationBarHidden(true, animated: animated) }
3. 清理冗余的模态样式设置
你同时给ViewController A和它所在的导航控制器设置了UIModalPresentationOverCurrentContext,这会导致上下文冲突。建议只保留导航控制器的模态样式设置,移除A的相关代码:
// 移除以下三行冗余代码 // tutorial.providesPresentationContextTransitionStyle = YES; // tutorial.definesPresentationContext = YES; // [tutorial setModalPresentationStyle:UIModalPresentationOverCurrentContext];
内容的提问来源于stack exchange,提问作者Rahul Vyas
相关产品推荐
相关产品推荐

