如何计算特定字体和字体大小的文本字符串的宽度?

时间:2009-08-24 19:52:38

标签: iphone cocoa-touch uikit

我有一个显示一些字符的UILabel。像“x”,“y”或“rpm”。如何计算标签中文本的宽度(它不是整个可用空间)?这适用于自动布局,如果UILabel内部有较小的文本,则另一个视图将具有更大的框架矩形。当指定UIFont和字体大小时,是否有方法来计算文本的宽度?也没有换行符,只有一行。

13 个答案:

答案 0 :(得分:67)

sizeWithFont:现已弃用,请改用sizeWithAttributes:

UIFont *font = [UIFont fontWithName:@"Helvetica" size:30];
NSDictionary *userAttributes = @{NSFontAttributeName: font,
                                 NSForegroundColorAttributeName: [UIColor blackColor]};
NSString *text = @"hello";
...
const CGSize textSize = [text sizeWithAttributes: userAttributes];

答案 1 :(得分:64)

您可以通过NSString UIKit Additions中的各种sizeWithFont:方法完成此操作。在您的情况下,最简单的变体应该足够(因为您没有多行标签):

NSString *someString = @"Hello World";
UIFont *yourFont = // [UIFont ...]
CGSize stringBoundingBox = [someString sizeWithFont:yourFont];

这种方法有几种变体,例如。有些人考虑换行模式或最大尺寸。

答案 2 :(得分:63)

由于sizeWithFont已被弃用,我只是要更新使用Swift 4和.size

的原始答案
//: Playground - noun: a place where people can play

import UIKit

if let font = UIFont(name: "Helvetica", size: 24) {
   let fontAttributes = [NSAttributedStringKey.font: font]
   let myText = "Your Text Here"
   let size = (myText as NSString).size(withAttributes: fontAttributes)
}

尺寸应为点“你的文字在这里”的屏幕尺寸。

答案 3 :(得分:34)

基于Glenn Howes' excellent answer,我创建了一个扩展来计算字符串的宽度。如果您正在设置UISegmentedControl的宽度,则可以根据片段的标题字符串设置宽度。

extension String {

    func widthOfString(usingFont font: UIFont) -> CGFloat {
        let fontAttributes = [NSAttributedString.Key.font: font]
        let size = self.size(withAttributes: fontAttributes)
        return size.width
    }

    func heightOfString(usingFont font: UIFont) -> CGFloat {
        let fontAttributes = [NSAttributedString.Key.font: font]
        let size = self.size(withAttributes: fontAttributes)
        return size.height
    }

    func sizeOfString(usingFont font: UIFont) -> CGSize {
        let fontAttributes = [NSAttributedString.Key.font: font]
        return self.size(withAttributes: fontAttributes)
    }
}

用法:

    // Set width of segmentedControl
    let starString = "⭐️"
    let starWidth = starString.widthOfString(usingFont: UIFont.systemFont(ofSize: 14)) + 16
    segmentedController.setWidth(starWidth, forSegmentAt: 3)

答案 4 :(得分:12)

Swift 4.2中的Oneliner

Sub get_cmd_info()
    Dim command As String
    command = Range("b2").Value

    MsgBox (command)

    If command = Get_info Then
        Get_function_name.Show
    End If

End Sub

答案 5 :(得分:5)

Swift中的这个简单扩展很有效。

extension String {
    func size(OfFont font: UIFont) -> CGSize {
        return (self as NSString).size(attributes: [NSFontAttributeName: font])
    }
}

用法:

let string = "hello world!"
let font = UIFont.systemFont(ofSize: 12)
let width = string.size(OfFont: font).width // size: {w: 98.912 h: 14.32}

答案 6 :(得分:5)

Swift-5

使用internalContentSize查找文本的高度和宽度。

print

即使您在字符串之间具有自定义的间距(如“ T E X T”

答案 7 :(得分:3)

雨燕4

extension String {
    func SizeOf(_ font: UIFont) -> CGSize {
        return self.size(withAttributes: [NSAttributedStringKey.font: font])
    }
}

答案 8 :(得分:2)

这适用于swift 2.3版本。你可以得到字符串的宽度。

var sizeOfString = CGSize()
if let font = UIFont(name: "Helvetica", size: 14.0)
    {
        let finalDate = "Your Text Here"
        let fontAttributes = [NSFontAttributeName: font] // it says name, but a UIFont works
        sizeOfString = (finalDate as NSString).sizeWithAttributes(fontAttributes)
    }

答案 9 :(得分:1)

Swift 3.0 +

extension String {
    func SizeOf_String( font: UIFont) -> CGSize {
        let fontAttribute = [NSFontAttributeName: font]
        let size = self.size(attributes: fontAttribute)  // for Single Line
       return size;
   }
}

像......一样使用它。

        let Str = "ABCDEF"
        let Font =  UIFont.systemFontOfSize(19.0)
        let SizeOfString = Str.SizeOfString(font: Font!)

答案 10 :(得分:1)

不确定这是多么有效,但是我编写了此函数,该函数返回的点大小将使字符串适合给定宽度:

func fontSizeThatFits(targetWidth: CGFloat, maxFontSize: CGFloat, font: UIFont) -> CGFloat {
    var variableFont = font.withSize(maxFontSize)
    var currentWidth = self.size(withAttributes: [NSAttributedString.Key.font:variableFont]).width

    while currentWidth > targetWidth {
        variableFont = variableFont.withSize(variableFont.pointSize - 1)
        currentWidth = self.size(withAttributes: [NSAttributedString.Key.font:variableFont]).width
    }

    return variableFont.pointSize
}

它将被这样使用:

textView.font = textView.font!.withSize(textView.text!.fontSizeThatFits(targetWidth: view.frame.width, maxFontSize: 50, font: textView.font!))

答案 11 :(得分:0)

我执行代码的方式是扩展UIFont :(这是Swift 4.1)

extension UIFont {


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

} // extension UIFont

答案 12 :(得分:0)

如果您想通过多行支持来获取文本宽度,则可以使用下一个代码( Swift 5 ):< / p>

func width(text: String, height: CGFloat) -> CGFloat {
    let attributes: [NSAttributedString.Key: Any] = [
        .font: UIFont.systemFont(ofSize: 17)
    ]
    let attributedText = NSAttributedString(string: text, attributes: attributes)
    let constraintBox = CGSize(width: .greatestFiniteMagnitude, height: height)
    let textWidth = attributedText.boundingRect(with: constraintBox, options: [.usesLineFragmentOrigin, .usesFontLeading], context: nil).width.rounded(.up)

    return textWidth
}

和如果需要的话,可以找到文本高度的方式相同(只需切换constraintBox实现):

let constraintBox = CGSize(width: maxWidth, height: .greatestFiniteMagnitude)

或者这是一个统一功能,可通过多行支持来获取文本大小:

func labelSize(for text: String, maxWidth: CGFloat, maxHeight: CGFloat) -> CGSize {
    let attributes: [NSAttributedString.Key: Any] = [
        .font: UIFont.systemFont(ofSize: 17)
    ]

    let attributedText = NSAttributedString(string: text, attributes: attributes)

    let constraintBox = CGSize(width: maxWidth, height: maxHeight)
    let rect = attributedText.boundingRect(with: constraintBox, options: [.usesLineFragmentOrigin, .usesFontLeading], context: nil).integral

    return rect.size
}

用法:

let textSize = labelSize(for: "SomeText", maxWidth: contentView.bounds.width, maxHeight: .greatestFiniteMagnitude)
let textHeight = textSize.height.rounded(.up)
let textWidth = textSize.width.rounded(.up)