You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何根据文本长度调整UIBarButtonItem的文字大小?

嘿,这个问题我之前做项目的时候也碰到过!UIBarButtonItem自带的title确实不太好处理超长文本溢出,给你整理了几个亲测有效的解决方案,按需选就行:

方案一:用自定义UIButton包装(最省心的通用方案)

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.21 06:39:49