如何将UIView添加至navigationItem.backBarButtonItem?附尝试代码
自定义导航返回按钮:把UIView作为返回按钮的正确姿势
嘿,我看你想把自定义的UIView(包含头像和名字)设置成导航栏的返回按钮,这里给你梳理下正确的实现方式,顺便纠正几个容易踩的坑:
首先得先搞清楚一个关键概念:navigationItem.backBarButtonItem是给上一个页面用的——比如你在A页面设置这个属性,当你push到B页面时,B页面的返回按钮才会显示你设置的内容。如果是想在当前页面的导航栏左侧显示自定义返回按钮,你应该用navigationItem.leftBarButtonItem,这是很多人一开始会搞混的点。
接下来给你完整的可运行代码,我优化了布局(用AutoLayout替代硬写frame,适配性更好),还处理了nil安全和点击逻辑:
// 先确保chat对象不为nil,或者给默认值做容错 guard let chat = chat else { return } // 1. 创建头像ImageView let contactImg = UIImageView() contactImg.image = UIImage(named: chat.Image) ?? UIImage(systemName: "person.circle") // 加个默认头像防止图片找不到 contactImg.layer.cornerRadius = 10 // 20x20的图,圆角设10刚好是圆形 contactImg.clipsToBounds = true // 必须加这个,否则圆角不生效 contactImg.contentMode = .scaleAspectFill // 保证图片不变形 contactImg.translatesAutoresizingMaskIntoConstraints = false // 2. 创建名字Label let contactName = UILabel() contactName.text = chat.Name contactName.font = UIFont.systemFont(ofSize: 17) contactName.textColor = .label // 自动适配暗黑模式 contactName.translatesAutoresizingMaskIntoConstraints = false // 3. 创建容器View,把头像和名字装进去 let backButtonView = UIView() backButtonView.addSubview(contactImg) backButtonView.addSubview(contactName) // 用AutoLayout布局子视图,适配所有屏幕 NSLayoutConstraint.activate([ // 头像的约束:20x20,垂直居中,左边留8px间距 contactImg.widthAnchor.constraint(equalToConstant: 20), contactImg.heightAnchor.constraint(equalToConstant: 20), contactImg.centerYAnchor.constraint(equalTo: backButtonView.centerYAnchor), contactImg.leadingAnchor.constraint(equalTo: backButtonView.leadingAnchor, constant: 8), // 名字的约束:垂直居中,左边跟头像间距8px,右边留8px间距 contactName.centerYAnchor.constraint(equalTo: backButtonView.centerYAnchor), contactName.leadingAnchor.constraint(equalTo: contactImg.trailingAnchor, constant: 8), contactName.trailingAnchor.constraint(equalTo: backButtonView.trailingAnchor, constant: -8), // 容器View的高度设为导航栏按钮标准高度44px backButtonView.heightAnchor.constraint(equalToConstant: 44) ]) // 4. 给容器View添加点击手势,模拟系统返回动作 let tapGesture = UITapGestureRecognizer(target: self, action: #selector(navigateBack)) backButtonView.addGestureRecognizer(tapGesture) backButtonView.isUserInteractionEnabled = true // 确保能响应点击 // 5. 把自定义View包装成UIBarButtonItem,设置到导航栏左侧 let customBackButton = UIBarButtonItem(customView: backButtonView) navigationItem.leftBarButtonItem = customBackButton
别忘了实现返回的方法:
@objc private func navigateBack() { navigationController?.popViewController(animated: true) }
几个重要的细节提醒:
- 一定要给ImageView加
clipsToBounds = true,不然圆角设置了也不会生效; - 用AutoLayout替代frame布局,能避免不同屏幕下的适配问题;
- 做了nil安全处理,防止
chat、chat.Image或chat.Name为空时崩溃; - 自定义View作为BarButtonItem时,默认没有点击事件,必须自己添加手势来实现返回逻辑;
如果你的需求是保留系统的返回箭头,只在箭头后面加自定义内容,那可以把系统箭头和你的自定义View放到一个容器里,或者用UIButton来组合箭头图标和自定义视图,实现起来也很简单。
内容的提问来源于stack exchange,提问作者Muhammad Sohaib Sultan
相关产品推荐
相关产品推荐

