У меня есть UILabel, который отображает некоторые символы. Как «x», «y» или «rpm». Как я могу рассчитать ширину текста на этикетке (она не занимает все доступное пространство)? Это для автоматического макета, когда другое представление будет иметь прямоугольник кадра большего размера, если внутри этого UILabel текст меньшего размера. Есть ли методы для расчета этой ширины текста, когда указаны UIFont и размер шрифта? Также нет разрыва строки и только одна строка.
82
Ответы:
Вы можете сделать это с помощью различных
sizeWithFont:
методов в дополнениях NSString UIKit . В вашем случае будет достаточно простейшего варианта (поскольку у вас нет многострочных меток):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) }
Размер должен соответствовать экранному размеру "Your Text Here" в пунктах.
источник
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.Обновление сентябрь 2019 г.
Этот ответ - гораздо более чистый способ сделать это с использованием нового синтаксиса.
Оригинальный ответ
Основываясь на отличном ответе Гленна Хауза , я создал расширение для вычисления ширины строки. Если вы делаете что-то вроде установки ширины 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)
источник
Стриж-5
Используйте intrinsicContentSize, чтобы найти высоту и ширину текста.
yourLabel.intrinsicContentSize.width
Это будет работать, даже если у вас есть настраиваемый интервал между строками, например "TEX T"
источник
Oneliner в Swift 4.2 🔸
let size = text.size(withAttributes:[.font: UIFont.systemFont(ofSize:18.0)])
источник
Это простое расширение в 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 4
extension String { func SizeOf(_ font: UIFont) -> CGSize { return self.size(withAttributes: [NSAttributedStringKey.font: font]) } }
источник
Это для быстрой версии 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!))
источник
Мой код - это расширение UIFont: (это Swift 4.1).
extension UIFont { public func textWidth(s: String) -> CGFloat { return s.size(withAttributes: [NSAttributedString.Key.font: self]).width } } // extension UIFont
источник