自定义导航栏按钮通过navigationItem.leftBarButtonItem,可能大家都知道,但关键点在于哪个控制器的navigationItem,举下面几种情况
一,UINavigationController+UIViewController,这种方式是常规的,没有问题
AppDelegate.m
ViewController *vc = [[ViewController alloc] init];
UINavigationController *nav = [[UINavigationController alloc] initWithRootViewController:vc]; self.window.rootViewController = nav;
ViewController.m
UIButton * leftBtn = [UIButton buttonWithType:UIButtonTypeCustom];
leftBtn.frame = CGRectMake(10, 7, 83, 30);
leftBtn.backgroundColor = [UIColor orangeColor];
UIBarButtonItem * leftItem = [[UIBarButtonItem alloc] initWithCustomView:leftBtn];
self.navigationItem.leftBarButtonItem = leftItem;
二,UINavigationController+UITabBarController+UIViewController,这种方式设置了没有效果
AppDelegate.m
UITabBarController *tabbar = [[UITabBarController alloc] init];
tabbar.view.backgroundColor = [UIColor greenColor];
ViewController *vc = [[ViewController alloc] init];
[tabbar addChildViewController:vc];
UIViewController *vc1 = [[UIViewController alloc] init];
vc1.view.backgroundColor = [UIColor yellowColor];
vc1.title = @"民宿";
[tabbar addChildViewController:vc1];
UINavigationController *nav = [[UINavigationController alloc] initWithRootViewController:tabbar];
nav.view.backgroundColor = [UIColor redColor];
self.window.rootViewController = nav;
ViewController.m
UIButton * leftBtn = [UIButton buttonWithType:UIButtonTypeCustom];
leftBtn.frame = CGRectMake(10, 7, 83, 30);
leftBtn.backgroundColor = [UIColor orangeColor];
UIBarButtonItem * leftItem = [[UIBarButtonItem alloc] initWithCustomView:leftBtn];
self.navigationItem.leftBarButtonItem = leftItem;
三,UINavigationController +UIViewController +UIViewController 这样设置也没有效果
AppDelegate.m
ViewController *vc = [[ViewController alloc] init];
UINavigationController *nav = [[UINavigationController alloc] initWithRootViewController:vc];
self.window.rootViewController = nav;
ViewController.m
ViewControllerB *viewB = [[ViewControllerB alloc] init];
[self addChildViewController:viewB];
ViewControllerB.m
// 自定义导航栏左侧按钮
UIButton * leftBtn = [UIButton buttonWithType:UIButtonTypeCustom];
leftBtn.frame = CGRectMake(10, 7, 83, 30);
leftBtn.backgroundColor = [UIColor orangeColor];
UIBarButtonItem * leftItem = [[UIBarButtonItem alloc] initWithCustomView:leftBtn];
self.navigationItem.leftBarButtonItem = leftItem;
self.view.backgroundColor = [UIColor purpleColor];
我就在考虑为什么有的可以有的不可以,每个UIViewController都有navigationItem,难道navigationItem不是都指向统一的navigationController.navigationBar的navigationItem,
查看官方文档
This is a unique instance of UINavigationItem created to represent the view controller when it is pushed onto a navigation controller. The first time the property is accessed, the UINavigationItem object is created. Therefore, you should not access this property if you are not using a navigation controller to display the view controller. To ensure the navigation item is configured, you can either override this property and add code to create the bar button items when first accessed or create the items in your view controller'��s initialization code.
我分别打印了UINavigationController,UITabBarController,UIViewController的navigationItem内存地址,结果不一样,和官方文档的说明一致,每个控制器都会新建一个navigationItem,至于把哪个navigationItem加到要显示的navigationBar上,主要是由[[UINavigationController alloc] initWithRootViewController:vc];导航控制器的根试图控制器决定的。
我打印出了,
self.navigationController.navigationBar.items.lastObject.leftBarButtonItems
结果和initWithRootViewController试图控制器里的navigationItem上的leftBarButtonItem的内存地址一致。(以自定义导航栏做按钮为示例,推理),navigationItem是只读的,我猜想是以navigationItem为媒介来操作leftBarButtonItem,至于苹果为什么这样设计,不是很明白,猜想会不会为了高内聚低耦合。。😆(补充一点,如果在控制器里直接设置
self.navigationController.navigationBar.items.lastObject.leftBarButtonItems = @[leftItem,leftItem1];
是可以的。。。。)
在寻找答案的过程中,也用了reveal工具来帮助我分析,在刚开始的分析中,我会问自己我怎么看不到控制器,怎么都是试图,慢慢的我领悟到,其实整个APP就是图层的叠加显示,是动态的图层,因为有网络和交互。而控制器只不过是人为的抽取出来来出来一个view上的所有试图的交互和逻辑。一点小心得记录一下,虽然可能对于别人而言早都理解了,但是对于我却是不小的欣喜。是从知道了到理解的质变。今天是腊八,口号,腊八腊八发发发,😄😄!