2

I am not sure how to update this code:

func textWidth(text: String, font: UIFont?) -> CGFloat
{
    let attributes = font?.fontDescriptor.fontAttributes
    return text.size(withAttributes: attributes).width
}

Swift 4 complain: Cannot convert value of type '[UIFontDescriptor.AttributeName : Any]?' to expected argument type '[NSAttributedStringKey : Any]?'

I don't know why they broke this, but it does not get automatically fixed.

MarkAurelius
  • 1,203
  • 1
  • 14
  • 27

3 Answers3

6

(SWIFT 4 Updated)

func textWidth(text: String, font: UIFont?) -> CGFloat {
    let attributes = font != nil ? [NSFontAttributeName: font] : [:]
    return text.size(withAttributes: attributes).width
}

Hope it helps.

Avinash Mishra
  • 797
  • 9
  • 19
  • Thanks, great minds think alike. That seems to be letter for letter the same as OOPer's solution of 27 June 17 I ended up using an extension of UIFont: public func textWidth(s: String) -> CGFloat { return s.size(withAttributes: [NSAttributedStringKey.font: self]).width } – MarkAurelius Jan 21 '18 at 23:25
  • @MarkAurelius Thanks Buddy :) – Avinash Mishra Jan 22 '18 at 04:22
5

I guess, you want to write something like this:

(Swift 4)

func textWidth(text: String, font: UIFont?) -> CGFloat {
    let attributes = font != nil ? [NSAttributedStringKey.font: font!] : [:]
    return text.size(withAttributes: attributes).width
}

(Swift 3)

func textWidth(text: String, font: UIFont?) -> CGFloat {
    let attributes = font != nil ? [NSFontAttributeName: font!] : [:]
    return text.size(attributes: attributes).width
}

fontAttributes is not a valid input for size(withAttributes:) (size(attributes:) in Swift 3) even if the type matches.

OOPer
  • 47,149
  • 6
  • 107
  • 142
0

An alternative way to do this in Swift 4, avoiding the handling of the optional, is like this:

  extension UIFont { 


    func textWidth(s: String) -> CGFloat
    {
        return s.size(withAttributes: [NSAttributedStringKey.font: self]).width
    }

}
MarkAurelius
  • 1,203
  • 1
  • 14
  • 27
  • that return wrong size for me :( let font = UIFont.systemFont(ofSize: 16) -> return CGSize(12 + font.textWidth(s: service.licenseName!), 50) -> wrong size, label does not show full text – famfamfam Oct 30 '19 at 04:33
  • Darn. Did any other approach work? That is early is Swift's history. – MarkAurelius May 28 '20 at 08:02