我有一个显示一些字符的UILabel。如“ x”,“ y”或“ rpm”。如何计算标签中文本的宽度(它不会占用整个可用空间)?这是用于自动布局的,如果UILabel内部包含较小的文本,则另一个视图将具有较大的框架矩形。指定UIFont和字体大小时,是否有方法来计算文本的宽度?也没有换行符,只有一行。
我有一个显示一些字符的UILabel。如“ x”,“ y”或“ rpm”。如何计算标签中文本的宽度(它不会占用整个可用空间)?这是用于自动布局的,如果UILabel内部包含较小的文本,则另一个视图将具有较大的框架矩形。指定UIFont和字体大小时,是否有方法来计算文本的宽度?也没有换行符,只有一行。
Answers:
您可以通过NSString UIKit Additions中的各种sizeWithFont:
方法来完成此操作。在您的情况下,最简单的变体就足够了(因为您没有多行标签):
NSString *someString = @"Hello World";
UIFont *yourFont = // [UIFont ...]
CGSize stringBoundingBox = [someString sizeWithFont:yourFont];
例如,此方法有多种变体。有些人考虑换行模式或最大尺寸。
由于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)
}
大小应为“此处您的文本”的屏幕大小(以磅为单位)。
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];
sizeWithAttributes:
方法返回小数位数;要使用返回的大小调整视图大小,必须使用ceil函数将其值提高到最接近的较大整数。
这个答案是使用新语法的一种更简洁的方法。
基于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)
}
}
用法:
// Set width of segmentedControl
let starString = "⭐️"
let starWidth = starString.widthOfString(usingFont: UIFont.systemFont(ofSize: 14)) + 16
segmentedController.setWidth(starWidth, forSegmentAt: 3)
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}
这是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)
}
如果您想通过多行支持来获取文本宽度,则可以使用下一个代码(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
}
同样,如果需要,可以找到文本高度(只需切换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)
对于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!)
不确定这样做的效率如何,但我编写了此函数,该函数返回的点大小将使字符串适合给定宽度:
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!))