如何根据文本长度调整UIBarButtonItem的文字大小?
嘿,这个问题我之前做项目的时候也碰到过!UIBarButtonItem自带的title确实不太好处理超长文本溢出,给你整理了几个亲测有效的解决方案,按需选就行:
UIBarButtonItem本身的titleLabel属性不好直接配置自动缩放手势,换用自定义UIButton作为它的customView就灵活多了,直接利用UIButton的自动字号调整属性就能搞定:
// 1. 创建自定义按钮 let customBarButton = UIButton(type: .system) customBarButton.setTitle("你的超长文本内容这里可以放很长很长的文字", for: .normal) // 2. 开启自动调整字号,设置最小缩放比例(比如0.5,意味着字号最小能缩到原字号的一半) customBarButton.titleLabel?.adjustsFontSizeToFitWidth = true customBarButton.titleLabel?.minimumScaleFactor = 0.5 // 3. 绑定点击事件 customBarButton.addTarget(self, action: #selector(barButtonTapped), for: .touchUpInside) // 4. 包装成UIBarButtonItem let barItem = UIBarButtonItem(customView: customBarButton) navigationItem.rightBarButtonItem = barItem // 点击事件实现 @objc func barButtonTapped() { // 你的业务逻辑 }
这个方案的优势是代码少、易维护,基本能覆盖绝大多数场景,文本会自动缩小到不溢出导航栏的尺寸。
方案二:计算文本宽度动态设置字号(精准控制字号范围)
如果你不想让字号缩得太小(比如最小不能低于12号),可以先计算文本在导航栏可用宽度下的最优字号,再手动设置:
// 计算最优字号的工具方法 func getOptimalFont(for text: String, maxAllowedWidth: CGFloat, minFontSize: CGFloat = 12) -> UIFont { var currentFontSize = UIFont.systemFontSize var textWidth = text.calculateWidth(with: UIFont.systemFont(ofSize: currentFontSize)) // 逐步减小字号,直到文本宽度符合要求或达到最小字号 while textWidth > maxAllowedWidth && currentFontSize > minFontSize { currentFontSize -= 1 textWidth = text.calculateWidth(with: UIFont.systemFont(ofSize: currentFontSize)) } return UIFont.systemFont(ofSize: currentFontSize) } // 给String扩展计算宽度的方法 extension String { func calculateWidth(with font: UIFont) -> CGFloat { let attributes: [NSAttributedString.Key: Any] = [.font: font] return self.size(withAttributes: attributes).width } } // 使用示例 let targetText = "这是一段超级超级长的UIBarButtonItem文本内容测试" // 导航栏右侧的可用宽度,可根据实际布局调整(比如减去左侧返回按钮的宽度,这里暂定150) let maxWidth: CGFloat = 150 let optimalFont = getOptimalFont(for: targetText, maxAllowedWidth: maxWidth) let barItem = UIBarButtonItem(title: targetText, style: .plain, target: self, action: #selector(barButtonTapped)) barItem.setTitleTextAttributes([.font: optimalFont], for: .normal) navigationItem.rightBarButtonItem = barItem
这个方案适合对字号有严格要求的场景,能保证文本既不溢出,又不会太小影响可读性。
方案三:允许换行+自动缩号(适合自定义高导航栏)
如果你的项目用了高于默认高度的导航栏,可以允许文本换行显示,同时配合自动缩号,能容纳更长的文本:
// 1. 创建自定义UILabel let customLabel = UILabel() customLabel.text = "这是一段允许换行的超长UIBarButtonItem文本内容,能显示两行哦" customLabel.numberOfLines = 2 // 设置允许显示的行数 customLabel.adjustsFontSizeToFitWidth = true customLabel.minimumScaleFactor = 0.6 customLabel.textAlignment = .center // 2. 给Label添加点击手势(因为UILabel默认不能响应点击) customLabel.isUserInteractionEnabled = true let tapGesture = UITapGestureRecognizer(target: self, action: #selector(labelTapped)) customLabel.addGestureRecognizer(tapGesture) // 3. 包装成UIBarButtonItem let barItem = UIBarButtonItem(customView: customLabel) navigationItem.rightBarButtonItem = barItem // 点击事件实现 @objc func labelTapped() { // 你的业务逻辑 }
这个方案需要导航栏有足够高度,适合文本特别长且允许换行的场景。
内容的提问来源于stack exchange,提问作者pjmanning
相关产品推荐
相关产品推荐

