11

Is there anything like the UILabel's adjustsFontSizeToFitWidth that can be used with a NSTextField?

Joshua Nozzi
  • 60,946
  • 14
  • 140
  • 135
  • Does this answer your question? [Get NSTextField contents to scale](https://stackoverflow.com/questions/2908704/get-nstextfield-contents-to-scale) – Jon Schneider Nov 01 '21 at 15:25

3 Answers3

2

In short: no. You have to do some brute force work to determine a string's -sizeWithAttributes: -boundingRectWithSize:options:attributes: with a given font size (set as an NSFont for NSFontAttributeName).

I'd start with a standard system font size and work down or up from there, depending on whether it's smaller or larger than the desired rectangle.

Joshua Nozzi
  • 60,946
  • 14
  • 140
  • 135
  • Pre-WWDC-2023 Update: It would be lovely to get iOS dynamic text in macOS. The system can optimize this far better than individual app devs can. – Joshua Nozzi Feb 09 '23 at 14:32
2

Swift 4 solution:

It will resize one by one until it fits, or until minimumFontSize = 3.

    let minimumFontSize = 3

    var sizeNotOkay = true
    var attempt = 0

    while sizeNotOkay || attempt < 15 { // will try 15 times maximun
        let expansionRect = textField.expansionFrame(withFrame: textField.frame)

        let truncated = !NSEqualRects(NSRect.zero, expansionRect)

        if truncated {
            if let actualFontSize : CGFloat = textField.font?.fontDescriptor.object(forKey: NSFontDescriptor.AttributeName.size) as? CGFloat {
                textField.font = NSFont.systemFont(ofSize: actualFontSize - 1)

                if actualFontSize < minimumFontSize {
                    break
                }
            }
        } else {
            sizeNotOkay = false
        }

        attempt += 1
    }
Jordan Osterberg
  • 289
  • 3
  • 18
ricardo
  • 1,221
  • 2
  • 21
  • 39
0

I came up with my own solution (its not a good solution!, just in case anyone couldn't find a better solution)

extension NSTextField {
    func fontSizeToFit() {
        if stringValue.count > 90 {
            font = NSFont.systemFont(ofSize: 40)
        } else {
            font = NSFont.systemFont(ofSize: CGFloat(120 - stringValue.count))
        }
    }
}
Ahmadreza
  • 6,950
  • 5
  • 50
  • 69