swiftxcodenstextfieldnstextfieldcell

Autosizing text in NSTextFieldCell (Swift 3) for MacOS App


My problem: I am building a MacOS app in Swift 3 and am looking to auto-resize (change font-size) text in a NSTextFieldCell, such that the text is always visible in its container.

I have come across Get NSTextField contents to scale but am not sure how to apply this to Swift 3 within my app. Does anyone have any advice or an explanation (or even link) on how to achieve my goal?


Solution

  • I've made a function that return a NSFont object :

    func calculateFont(toFit textField: NSTextField, withString string: NSString, minSize min: Int, maxSize max: Int) -> NSFont {
        for i in min...max {
            var attr: [String: Any] = [:] as Dictionary
            attr[NSFontSizeAttribute] = NSFont(name: textField.font!.fontName, size: CGFloat(i))!
            let strSize = string.size(withAttributes: [NSFontAttributeName: NSFont.systemFont(ofSize: CGFloat(i))])
            let linesNumber = Int(textField.bounds.height/strSize.height)
            if strSize.width/CGFloat(linesNumber) > textField.bounds.width {
                return (i == min ? NSFont(name: "\(textField.font!.fontName)", size: CGFloat(min)) : NSFont(name: "\(textField.font!.fontName)", size: CGFloat(i-1)))!
            }
        }
        return NSFont(name: "\(textField.font!.fontName)", size: CGFloat(max))!
    }
    

    You can use it like that :

        // set multines
        self.textField.lineBreakMode = .byWordWrapping // this looks like it doesn't work, set it in the storyboard instead
        self.textField.maximumNumberOfLines = 100
        // set font
        self.textField.font = self.calculateFont(toFit: self.textField, withString: self.textField.stringValue as NSString, minSize: 8, maxSize: 50)
    

    Tell me if that works for you