如何通过内置函数获取适配指定宽度的NSFont字号?
适配指定宽度的NSFont字号计算:替代while循环的更优方案
嘿,好问题!确实不用靠低效的while循环逐次调整字号来实现这个需求——虽然没有一步到位直接返回适配宽度的最大字号的系统内置函数,但有两种更优雅高效的方式来搞定:
先提一句你现有代码的小问题
你的while循环条件fontsize.width==fcsize放在fontsize.width<fcsize的分支里,这意味着循环根本不会执行,逻辑上是有问题的;而且就算修正条件,逐次+1的方式效率也很低,尤其是当需要调整的字号跨度大的时候。
方案1:用二分查找替代逐次迭代(手动计算场景)
二分查找的时间复杂度是O(log n),比逐次尝试的O(n)高效得多。结合NSString.size(withAttributes:)就能快速找到适配指定宽度的最大字号:
func findMaxFontSize(for text: String, fontName: String, targetWidth: CGFloat) -> CGFloat { guard !text.isEmpty else { return 0 } // 设定字号的上下限,可根据你的需求调整 var minSize: CGFloat = 1 var maxSize: CGFloat = 200 var bestFitSize: CGFloat = minSize // 迭代10次足够达到高精度的字号值了 for _ in 0..<10 { let midSize = (minSize + maxSize) / 2 guard let font = NSFont(name: fontName, size: midSize) else { maxSize = midSize continue } let textAttributes: [NSAttributedString.Key: Any] = [.font: font] let textSize = (text as NSString).size(withAttributes: textAttributes) if textSize.width <= targetWidth { // 当前字号能适配宽度,尝试更大的字号 bestFitSize = midSize minSize = midSize } else { // 当前字号太宽,尝试更小的字号 maxSize = midSize } } return bestFitSize }
方案2:利用系统自动调整功能(UI控件场景)
如果你是在NSTextField这类UI控件里显示文本,直接开启系统的自动字号适配功能最省心,完全不用手动计算:
let textField = NSTextField() textField.stringValue = "需要显示的文本内容" // 设置初始字体和字号 textField.font = NSFont(name: "Helvetica", size: 16) // 开启自动适配宽度的字号调整 textField.cell?.adjustsFontSizeToFitWidth = true // 可选:设置最小字号下限,避免字号过小无法阅读 textField.cell?.minimumFontSize = 8 // 确保文本不换行,强制单行适配宽度 textField.cell?.wraps = false textField.cell?.usesSingleLineMode = true
开启adjustsFontSizeToFitWidth后,系统会自动根据控件宽度调整字号,让文本刚好能在单行内显示,完全不用自己写循环。
内容的提问来源于stack exchange,提问作者techno
相关产品推荐
相关产品推荐

