IOS导航栏的问题
ios 两个状态栏 背景图片不一样 push过去正常显示
返回(pop)回来,当前的背景图变成了push过去的那个导航栏的背景图片.
用图片演示:
1.这是控制器A:
2.设置push过去的控制器B:
3.点击返回
后的控制器A:
为什么控制器A的导航栏的背景图片变成了控制器B的?如何修改?
代码奉上:自定义控制器
的所有代码:
#import "LMSNavigationController.h"@interface LMSNavigationController ()
@end
@implementation LMSNavigationController
- (void)viewDidLoad {
[super viewDidLoad];
[self.navigationBar setTitleTextAttributes:
@{NSFontAttributeName:[UIFont systemFontOfSize:16]}];
}
/**
* 在这个方法中拦截所有push进来的控制器
*/
- (void)pushViewController:(UIViewController *)viewController animated:(BOOL)animated
{
if (self.childViewControllers.count > 0) {
// 如果push进来的不是第一个控制器
UIButton *leftBtn = [UIButton buttonWithType:UIButtonTypeCustom];
[leftBtn setImage:[UIImage imageNamed:@"nav-back.png"] forState:UIControlStateNormal];
[leftBtn setImage:[UIImage imageNamed:@"nav-back-hi.png"] forState:UIControlStateHighlighted];
leftBtn.frame = CGRectMake(0, 0, 30, 30);
[leftBtn addTarget:self action:@selector(popViewControllerAnimated:) forControlEvents:UIControlEventTouchUpInside];
viewController.navigationItem.leftBarButtonItem = [[UIBarButtonItem alloc]initWithCustomView:leftBtn];
// 隐藏tabbar
viewController.hidesBottomBarWhenPushed = YES;
}
//把导航栏底部的横线去掉
[self.navigationBar setShadowImage:[UIImage new]];
// 这句super的push要放在后面, 让viewController可以覆盖上面设置的leftBarButtonItem
// 意思是,我们任然可以重新在push控制器的viewDidLoad方法中设置导航栏的leftBarButtonItem,如果设置了就会覆盖在push方法中设置的“返回”按钮,因为 [super push....]会加载push的控制器执行viewDidLoad方法。
[super pushViewController:viewController animated:animated];
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
@end
控制器A关键代码:
- (void)viewDidLoad { [super viewDidLoad];
//导航栏透明背景(nav-clearcolor-image是一张透明的图片)
[self.navigationController.navigationBar setBackgroundImage:[UIImage imageNamed:@"nav-clearcolor-image"] forBarMetrics:UIBarMetricsDefault];
//把导航栏底部的横线去掉
[self.navigationController.navigationBar setShadowImage:[UIImage new]];
//不显示文字
self.navigationItem.title = nil;
}
控制器B关键代码:
- (void)viewDidLoad { [super viewDidLoad];
UILabel *titleLabel = [[UILabel alloc]init];
titleLabel.text = @"push过来的控制器";
titleLabel.textColor = TitleTextColor;
[titleLabel sizeToFit];
self.navigationItem.titleView = titleLabel;
}
回答:
这是个关于 UINavigationController
(假设你们的 LMSNavigationController
是它的子类)以及 UIViewController
(后文简称 VC )生命周期的问题。。。
简单版本的答案
把 VC A 的 viewDidLoad
改成 viewWillAppear
。
(下面还有个感觉上更优的办法。)
复杂版本(也杂不到哪去。。。)
先看看文档对 viewDidLoad 是怎么描述的:
Called after the controller's view is loaded into memory.
在 VC 的视图加载进内存的时候,这个方法会被调用。VC B pop
出去的时候不符合调用 VC A 的 viewDidLoad
的条件,解释如下:
UINavigationController
维护着一个 VC 栈,你 push
、pop
那些 VC 时都是在操作这个栈。
push
的时候它会创建一个新的 VC 压入栈中,就是你的 VC B,这个过程中这个新的 VC B 绑定的 view
经历了被加入内存的过程, viewDidLoad
被调用。 VC B 处于栈顶,成为 topViewController
。 VC A 不再处于栈顶,但仍处于栈中,与它关联的 view
仍在内存中。再 pop
VC B 出去的时候,VC A 关联的 view 的 viewDidLoad
不再被调用。
所以 push
pop
具体调用了什么?
上图
Figure 1-5 Messages sent during stack changes
图片来源:Navigation Controller 文档的 Monitoring Changes to the Navigation Stack 部分
Monitoring Changes to the Navigation Stack
监控导航栈的变化
以 push
VC B 出去为例:
VC B 作为当前的 Topmost view controller ,其
viewWillDispear
最先被调用VC A 的
viewWillAppear
被调用UINavigationControllerDelegate
的navigationController:willShowViewController:animated:
被调用转场动画(完成?不清楚)
VC B 的
viewDidDispear
被调用VC A 的
viewDidAppear
被调用UINavigationControllerDelegate
的navigationController:didShowViewController:animated:
被调用
综上, VC A 的 viewDidLoad
改成 viewWillAppear
即可。
然而个人感觉更好的办法是把两个 viewDidLoad
都拆了,逻辑重写在 UINavigationControllerDelegate
的 navigationController:willShowViewController:animated:
中。即可在一个位置解决改背景图这个需求。
完。
更新,上面说的用 UINavigationControllerDelegate
的办法:
func navigationController(navigationController: UINavigationController, willShowViewController viewController: UIViewController, animated: Bool) { if self.childViewControllers.count > 1 {
navigationController.navigationBar.setBackgroundImage(UIImage(named: "a"), forBarMetrics: .Default)
} else {
navigationController.navigationBar.setBackgroundImage(UIImage(named: "b"), forBarMetrics: .Default)
}
}
viewWillAppear
也试了,跟这个一模一样,没出现黑框。就这个问题而言,这两个地方就是符合你要求的。怎么选看自己喜欢就好。
系统自带的导航控制器在动画开始前已经做完了该做的事,不会出现动画到一半图片才载入完。最差也就是动画开始前卡住几秒,载入完才开始。
你们的导航控制器是自己定制的,检查定制的部分哪里有问题导致的黑框。
(另。。还是没看到背景图在哪改了。不是第一个控制器那里改的是按钮图片啊)
回答:
nav 下的所有 VC 是通用同一个 navBar 的
你在进入 B 的时候修改了 navBar
但是在退出 B 的时候没有改回来
回答:
你有2个导航栏控制器 (pop)回去的导航栏是跟当前的导航栏一样的,应该搞个代理就重新赋值就可以了。(不过比较麻烦)
回答:
你肯定在B中修改了导航条的色或者图了吧
回答:
在A的viewWillAppear方法里面再设置一遍vc的背景图片试试
以上是 IOS导航栏的问题 的全部内容, 来源链接: utcz.com/p/184343.html