Swift自定义导航栏titleView:添加带UIView子视图后子视图不显示求助
嘿,我来帮你揪出导航栏titleView子视图不显示的问题!结合你给出的代码片段,大概率是这几个常见坑导致的:
1. 容器视图的frame设置不合理
你把titleContainer的frame直接设成了整个屏幕的大小:
titleContainer.frame = CGRect(x: 0, y: 0, width: UIScreen.main.bounds.size.width, height: UIScreen.main.bounds.size.height)
导航栏的titleView有自身的布局限制,这么大的尺寸会被导航栏自动压缩,甚至直接导致容器视图被“挤消失”。正确的做法是给容器设置适配导航栏的合理尺寸,或者用AutoLayout来约束布局,而非硬写屏幕大小。
2. 错误操作了子视图的layer.frame
你写的searchIcon.layer.frame是错误的!应该直接设置searchIcon.frame——视图的layer.frame是跟随view本身的frame的,手动修改layer.frame会导致视图布局错乱。而且你的代码在这里截断了,大概率y坐标用了屏幕高度计算,这会让按钮直接跑到容器视图外面,自然看不到。
3. 大概率遗漏了添加子视图到容器
你的代码片段里没看到titleContainer.addSubview(searchIcon)这一行!如果没把按钮添加到容器视图中,那肯定不会显示,这是最容易忽略的细节。
4. 未设置容器视图的内在尺寸
导航栏的titleView依赖视图的intrinsicContentSize来确定布局,如果titleContainer没有设置这个属性,导航栏可能会把它的尺寸计算为0,导致子视图无法显示。可以通过重写intrinsicContentSize或给容器添加宽高约束来解决。
这里给你一个用AutoLayout实现的可靠版本(适配所有机型):
// 创建容器视图,关闭自动转换约束 let titleContainer = UIView() titleContainer.translatesAutoresizingMaskIntoConstraints = false // 创建搜索按钮 let searchIcon = UIButton(type: .system) searchIcon.setImage(UIImage(named: "search_icon"), for: .normal) searchIcon.translatesAutoresizingMaskIntoConstraints = false // 关键步骤:把按钮添加到容器 titleContainer.addSubview(searchIcon) // 添加第二个子视图(比如标题标签) let titleLabel = UILabel() titleLabel.text = "我的页面" titleLabel.textAlignment = .center titleLabel.translatesAutoresizingMaskIntoConstraints = false titleContainer.addSubview(titleLabel) // 用AutoLayout约束所有视图 NSLayoutConstraint.activate([ // 约束搜索按钮在容器左侧 searchIcon.leadingAnchor.constraint(equalTo: titleContainer.leadingAnchor), searchIcon.centerYAnchor.constraint(equalTo: titleContainer.centerYAnchor), searchIcon.widthAnchor.constraint(equalToConstant: 44), searchIcon.heightAnchor.constraint(equalToConstant: 44), // 约束标题标签在按钮右侧,填充剩余空间 titleLabel.leadingAnchor.constraint(equalTo: searchIcon.trailingAnchor, constant: 8), titleLabel.trailingAnchor.constraint(equalTo: titleContainer.trailingAnchor), titleLabel.centerYAnchor.constraint(equalTo: titleContainer.centerYAnchor), // 给容器设置合适的宽高 titleContainer.heightAnchor.constraint(equalToConstant: 44), titleContainer.widthAnchor.constraint(greaterThanOrEqualToConstant: 120) ]) // 绑定到导航栏 navigationItem.titleView = titleContainer
如果偏好用frame布局,也要确保子视图的frame在容器范围内:
let titleContainer = UIView(frame: CGRect(x: 0, y: 0, width: 150, height: 44)) let searchIcon = UIButton(frame: CGRect(x: 0, y: 0, width: 44, height: 44)) searchIcon.setImage(UIImage(named: "search_icon"), for: .normal) titleContainer.addSubview(searchIcon) let titleLabel = UILabel(frame: CGRect(x: 52, y: 0, width: 98, height: 44)) titleLabel.text = "我的页面" titleLabel.textAlignment = .center titleContainer.addSubview(titleLabel) navigationItem.titleView = titleContainer
对照你的代码检查一下,修正这些点后子视图应该就能正常显示啦!
内容的提问来源于stack exchange,提问作者N. Beer

