前言 self.navigationItem.titleView的位置跟leftBarButtonItem,rightBarButtonItem的大小有关。
leftBarButtonItem,导航条中左侧button。
rightBarButtonItem,导航条中右侧button。
titleview,不用介绍了吧,就是标题。
titleview的起点位置和尺寸依赖于leftBarButtonItem和rightBarButtonItem的位置,所以需要先设置leftBarButtonItem和rightBarButtonItem的位置。
注意点
假设leftBarButtonItem和rightBarButtonItem之间的空白长度为emptyLength:
则当titleView的长度小于emptyLength,titleView就会居中。所以可以设置titleView到一定长度来达到居中效果。
有时候rightBarButtonItem会很长
rightBarButtonItem很长的时候会把titleView往左边挤过去,这样不管你怎么调titleView长度都无法居中。
这种情况可以设置rightBarButtonIte的长度和leftBarButtonItem一样,rightBarButtonItem里面只是放一个长度和leftBarButtonItem一样的view1,再把很长的子视图subView1加入到这个view1中,view1设置clipsToBounds = NO(让超出父视图的部分也显示)
但是如果titleView比较长会把subView1挡住,view1只显示部分子视图:
iOS11.0之前
在iOS11.0之前这个问题比较好解决,只要设置视图的层级,把被挡住的subView1调整到最前面
[self.navigationController.navigationBar bringSubviewToFront:view1];
iOS11.0以后
这时候可以通过
[self.navigationController.navigationBar insertSubview:view1 aboveSubview:_titleView];
来添加右边的导航栏按钮了,而不是通过设置self.navigationItem.rightBarButtonItem
。这边需要调整view1的frame到self.navigationItem.rightBarButtonItem
的位置,这样就达到我们想要的titleView居中效果,当然这时候计算titleView的最大长度还是结合view1,还是把view1当做self.navigationItem.rightBarButtonItem
来计算处最大emptyLength值。
emptyLength
如果前面直接给定了一个比较小的titleView长度,就不需要这一步计算,titleView已经居中了,如果titleView比较长不固定,就需要计算emptyLength,并且最终设置的titleView的长度要小于emptyLength。
(1)如果只是设置了titleView,没有设置barbutton,把titleview的宽度设置为屏幕宽度,则titleview距离屏幕的边距,iOS11之前,在iPhone6p上是20p,在iPhone6p之前是16p;iOS11之后,在iPhone6p上是12p,在iPhone6p之前是8p。
(2)如果只是设置了barbutton,没有设置titleview,则在iOS11里,barButton距离屏幕的边距是20p和16p;在iOS11之前,barButton距离屏幕的边距也是20p和16p。
(3)如果同时设置了titleView和barButton,则在iOS11之前,titleview和barbutton之间的间距是6p,在iOS11上titleview和barbutton之间无间距
居于以上,我这边按最大值来扣除导航栏左右按钮的间距emptyLength = self.navigationController.navigationBar.frame.size.width - (20.0 + 12.0 + 16.0 + 左右按钮的长度)。得出emptyLength,只要设置titleView比emptyLength小即可达到居中效果。
后记
导航栏右边按钮可能涉及到点击范围问题,这个可以修改hitTest,这边就懒惰些,不讨论。