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(-);
}];

titleView发生偏移、titleView与masonry、titleView的设置、titleView的使用的更多相关文章

  1. swift项目第八天:自定义转场动画以及设置titleView的状态

    如图效果: 一:Home控制器 /* 总结:1:设置登陆状态下的导航栏的左右按钮:1:在viewDidLoad里用三目运算根据从父类继承的islogin的登陆标识来判断用户是否登陆来显示不同的界面.未 ...

  2. iOS 11 导航栏 item 偏移问题 和 Swift 下 UIButton 设置 title、image 显示问题

    html,body,div,span,applet,object,iframe,h1,h2,h3,h4,h5,h6,p,blockquote,pre,a,abbr,acronym,address,bi ...

  3. WinForm搭载ScintillaNET时文本由于发生偏移被隐藏解决方案

    项目用ScintillaNet搭载到WinForm以满足文本编辑的需求,在用FindReplace.Scintilla.Text=“显示内容”输出文本内容的时候会碰到文本被WinForm边框隐藏的情况 ...

  4. tableview 位置发生偏移

    状况描述:1.首次进入该界面时正常 2.push了新的界面后,再返回该界面 tableview和导航栏直接出现了间隔区域 tableview为代码创建 _tableView =  [[UITableV ...

  5. 在使用NavigationController情况下的布局的Y轴的起始位置

    在有的时候,当一个ViewController被push进一个NavigationController的时候,view上会有一个高度为64的NavigationBar(除非主动隐藏了Navigatio ...

  6. margin负边距的使用(超简单)

    写在开头: 在css的世界中,一切都是框,所有的框都处于流动的状态 margin负边距可以使文档流发生偏移   在没有设置margin-bottom的时候,parent的高度会跟随child的内部元素 ...

  7. iOS中navigationItem的titleView如何居中

    开发过程中,发现titleview很难居中,通过各种尝试终于找到了解决方法. 首先清楚你个概念: leftBarButtonItem,导航条中左侧button. rightBarButtonItem, ...

  8. 设置导航栏 self.navigationItem.titleView 居中

    喜欢交朋友的加:微信号 dwjluck2013-(void)viewDidLayoutSubviews{ [self setDisplayCustomTitleText:@"每日头条&quo ...

  9. (十六)WebGIS中偏移补偿量引发的问题之探讨

    文章版权由作者李晓晖和博客园共有,若转载请于明显处标明出处:http://www.cnblogs.com/naaoveGIS/. 1.背景 在上一章里讲解地图平移功能的实现时,我在最后提出了两个问题: ...

随机推荐

  1. js兼容安卓和IOS的复制文本到剪切板

    1.在做点击按钮复制功能时遇到了小小的卡顿,此处遇到了两种系统手机的兼容性 / 复制后会对文本进行选中 / 输入法弹出 等.现将方法进行总结,如下代码很好对解决了以上问题,适用性强. 2.在文本此处使 ...

  2. dp(多重背包)

    有 NN 种物品和一个容量是 VV 的背包. 第 ii 种物品最多有 sisi 件,每件体积是 vivi ,价值是 wiwi . 求解将哪些物品装入背包,可使物品体积总和不超过背包容量,且价值总和最大 ...

  3. 使用PIE.htc 进行IE兼容CSS3

    步骤: 1.引入文件.注意PIE.htc文件和css文件要放在同一个目录下: 2.在css元素中加上  behavior:url(pie.htc); 3.可以愉快的写css hack啦 ,这时需要的圆 ...

  4. 使用session在jsp页面之间传递多维数组,用于实现全局变量的效果

    使用session在jsp页面之间传递多维数组:发送数据的jsp页面:int [][] form_number=new int[4][4]; session.setAttribute("se ...

  5. python学习HTML之CSS

    1.sytle属性设置 . <head> <meta charset="UTF-8"> <title>Title</title> & ...

  6. 棍子Sticks(poj_1011)[经典搜索]

    [题意描述] George用相同的长度棍子,将他们随机切成最多64个单位的长度,现在,他想回到原来的状态,但他忘了他原来的多少根,以及他们原本是多长.请帮助他和设计一个程序,计算最小的可能的原始长度. ...

  7. 【代码总结】SQL语句设计

    1.根据空值(NULL)检索条件 select * from user where age is not null; //查询年龄为null的所有用户 2.使用IN进行范围对比查询 ,5的所有用户 , ...

  8. 比较好的IT教程网

    MDN最完整的Web标准,Webapi                https://developer.mozilla.org/zh-CN/docs/Web 主要几个比较常用教程网都可以 gitbo ...

  9. Codeforces Round #618 (Div. 2)A. Non-zero

    Guy-Manuel and Thomas have an array aa of nn integers [a1,a2,…,an ]. In one step they can add 11 to ...

  10. nodejs的forEach不支持break打断