navigationItem的titleView属性的设置本身是很简单的,容易出问题的原因是自动化布局与frame混用造成的。

本文一步一步的讲解,力求找到问题的起源。如果你也在这块同样遇到问题,不妨耐下心来,一起看看怎么回事。

titleView这个属性默认值是nil。也就是说,它是不存在的。如果开发者使用[self.navigationItem.titleView addsubView:customView];是没有作用的,虽然OC语法采用的消息机制,向nil发送消息是不会出现异常的,但是这样做是不能将customView展现出来。

正确的姿势,是将customView对象赋值给titleView属性。那么customView对象的CGRect值如何设置呢?这是一个好问题,弄清楚这个问题之前,需要弄明白titleView的可用区域。

问题一:titleView的可用区域以及其所处位置

导航栏上面是状态栏(用来显示电池、时间等信息),状态栏的高度是20px。

导航栏的高度是44px(但是如果将UISearchController中的属性searchBar作为导航栏的titleView,在iOS11以后,导航栏的高度将不再是44,而是56。接下来的话,需要对导航栏上面的其他控件,比如返回按钮重新进行位置的调整)。

导航栏可以设置背景色(backgroundColor)、背景图片(background)、左按钮组(leftBarButtonItems)、右按钮组(rightBarButtonItems)、标题(title)、标题视图(titleView)。

它们之间的在可用区域的制衡上是这样的:如果设置了titleView,那么title就视为无效。导航栏中去除左按钮组占用的区域和右按钮组占用的区域之后,剩下的的横向区域才是留给titleView使用的。那titleView的纵向区域有多少呢?44px。

因此,customView的frame的orign不管为多少,都无济于事。titleView在乎的是customView的size,它会在titleView的可用区域内,尽量地保证customView在导航栏上居中(水平居中+竖直居中)。注意,不是在titleView的可用区域上居中!另外size的宽和高如果超出有效值,那么视为最大的有效值。

比如,如果设置customView的frame是(60,-20,200,80)。我们来分析下,首先,orign(60,-20)直接视为无效。然后通过左按钮组和右按钮组占用的区域,计算出来的横向可用值为270,那么200视为有效。有效的最大高度是44,这里设置的80,视为有效值的最大值即44。这样一系列的转换下来,用自然语言表达就是:customView的宽高为200*44,整体在导航栏上面地布局,请允许我用图形表示:

本来是想文字表述出来的,但是我觉得还是没有直接看图直观。

文章写到这里,需要稍微收拢下了,不然容易失去重心。接下来需要考虑的问题是,titleView的frame如何设置。

结论是这样的,事情本来很简单的,注意一点,如果用来赋值给titleView的customView使用frame,那么其内部的子view对象的布局也使用frame。如果customView使用masonry,那么其内部的子view对象布局也要使用masonry。

看下代码吧:

UIControl *bgView = [[UIControl alloc] initWithFrame:CGRectMake(, ,  , )];
bgView.backgroundColor = [UIColor redColor];
bgView.layer.cornerRadius = .f;
bgView.layer.masksToBounds = YES;
[bgView addTarget:self action:@selector(searchBeginAction) forControlEvents:UIControlEventTouchUpInside]; self.navigationItem.titleView = bgView;

或者是

 UIControl *bgView = [[UIControl alloc] initWithFrame:CGRectZero];
bgView.backgroundColor = [UIColor colorWithHexString:@"#4B9DDB"];
bgView.layer.cornerRadius = .f;
bgView.layer.masksToBounds = YES;
[bgView addTarget:self action:@selector(searchBeginAction)
forControlEvents:UIControlEventTouchUpInside];
[bgView mas_makeConstraints:^(MASConstraintMaker *make) {
make.size.mas_equalTo(CGSizeMake(SCREEN_WIDTH - , ));
}]; self.navigationItem.titleView = bgView; UIImageView *searchImage = [[UIImageView alloc] initWithImage:[UIImage
imageNamed:@"icon_nav_search"]];
[bgView addSubview:searchImage];
[searchImage mas_makeConstraints:^(MASConstraintMaker *make) {
make.left.mas_equalTo(bgView).offset();
make.centerY.mas_equalTo(bgView);
make.size.mas_equalTo(CGSizeMake(, ));
}];
UITextField *searchTextField = [[UITextField alloc] init];
searchTextField.textColor = [UIColor colorWithHexString:@"#ffffff"];
searchTextField.userInteractionEnabled = NO;
searchTextField.font = SYSTEMFONT_14;
searchTextField.placeholder = @"搜感兴趣的活动";
[searchTextField setValue:[UIColor whiteColor] forKeyPath:@"_placeholderLabel.textColor"];
[bgView addSubview:searchTextField];
[searchTextField mas_makeConstraints:^(MASConstraintMaker *make) {
make.left.mas_equalTo(searchImage.mas_right).offset();
make.centerY.mas_equalTo(bgView);
make.right.mas_equalTo(bgView.mas_right).offset(-);
}];

最新文章

  1. 更新过程 renewal process
  2. swift中 if let 与 guard let 对比,guard会降低一个分支
  3. App开发流程之加密工具类
  4. Newtonsoft.Json 序列化和反序列化 时间格式
  5. [2014.01.27]wfImage 图像处理组件 3.3
  6. 亿级Web系统的高容错性实践
  7. Android动画及图片的缩放和旋转
  8. PowerShell - Read an Excel file using COM Interface
  9. [Ubuntu] ubuntu13.04 从php5.4降级到php5.3
  10. Java中的String为什么是不可变的?
  11. 各种常用函数 (SQL)
  12. Portal:十大免费建站程序推荐
  13. 用户输出表单处理php
  14. 理解Java多态
  15. server宕机监控、检測、报警程序(139绑定手机短信报警)monitor_down.sh
  16. 一天一个类--ArrayList之一
  17. javascript 事件响应
  18. ubuntu下安装ssh服务器方法
  19. C语言的第 次作业总结
  20. Error:"Java patch PatchPasswordEncryption_J10001 is being applied by some other process" when starting Ranger Admin

热门文章

  1. Eclipse安装配置java项目
  2. Python学习(一)——开发语言和Python的安装
  3. SQL中AVG、COUNT、SUM、MAX等聚合函数对NULL值的处理
  4. ES-windows版本设置远程访问
  5. json 字符串 <----> json 对象
  6. RTT学习之PWM、ADC设备
  7. 企业面试问题收集-java基础
  8. 第八届极客大挑战 Re
  9. 【Android】数据存储和访问
  10. redis场景分析的很到位