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

63 iphone cocoa-touch uikit

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

wco*_*ran 71

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];
Run Code Online (Sandbox Code Playgroud)

  • 注意:`sizeWithAttributes:`方法返回小数大小; 要使用返回的大小来调整视图大小,必须使用ceil函数将其值提升到最接近的更高整数. (7认同)

Gle*_*wes 68

由于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)
}
Run Code Online (Sandbox Code Playgroud)

大小应该是屏幕上的"你的文字在这里"的大小.


Dan*_*ser 66

你可以通过NSString UIKit Additions中的各种sizeWithFont:方法做到这一点.在您的情况下,最简单的变体应该足够(因为您没有多行标签):

NSString *someString = @"Hello World";
UIFont *yourFont = // [UIFont ...]
CGSize stringBoundingBox = [someString sizeWithFont:yourFont];
Run Code Online (Sandbox Code Playgroud)

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

  • "sizeWithFont:"已弃用.wcochran的回答应该是标记的. (11认同)
  • 由于您具有绿色复选标记,因此应更改使用sizeWithAttributes的答案. (4认同)

Adr*_*ian 40

基于Glenn Howes的优秀答案,我创建了一个扩展来计算字符串的宽度.如果您正在执行类似设置a的宽度的操作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)
    }
}
Run Code Online (Sandbox Code Playgroud)

用法:

    // Set width of segmentedControl
    let starString = "??"
    let starWidth = starString.widthOfString(usingFont: UIFont.systemFont(ofSize: 14)) + 16
    segmentedController.setWidth(starWidth, forSegmentAt: 3)
Run Code Online (Sandbox Code Playgroud)


eon*_*ist 16

Oneliner在Swift 4.2中

let size = text.size(withAttributes:[.font: UIFont.systemFont(ofSize:18.0)])
Run Code Online (Sandbox Code Playgroud)


Alo*_*lok 15

斯威夫特5

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

yourLabel.intrinsicContentSize.width

即使您在字符串之间具有自定义的间隔(例如“ TEX T”),此方法也将起作用


Lak*_*ngh 7

对于斯威夫特 5.4

extension String {
    func SizeOf_String( font: UIFont) -> CGSize {
        let fontAttribute = [NSAttributedString.Key.font: font]
        let size = self.size(withAttributes: fontAttribute)  // for Single Line
       return size;
    }
}
Run Code Online (Sandbox Code Playgroud)

使用它就像...

        let Str = "ABCDEF"
        let Font =  UIFont.systemFontOfSize(19.0)
        let SizeOfString = Str.SizeOfString(font: Font!)
Run Code Online (Sandbox Code Playgroud)


JsW*_*JsW 6

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

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

用法:

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


ate*_*kov 6

如果您正在努力通过多行支持获得文本宽度,那么您可以使用下一个代码(Swift 5):

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
}
Run Code Online (Sandbox Code Playgroud)

如果需要,您可以通过同样的方式找到文本高度(只需切换约束框实现):

let constraintBox = CGSize(width: maxWidth, height: .greatestFiniteMagnitude)
Run Code Online (Sandbox Code Playgroud)

或者这里有一个统一的函数来获得多行支持的文本大小:

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
}
Run Code Online (Sandbox Code Playgroud)

用法:

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