Ich habe ein UILabel, das einige Zeichen anzeigt. Wie "x", "y" oder "U / min". Wie kann ich die Breite des Textes auf dem Etikett berechnen (es wird nicht der gesamte verfügbare Platz beansprucht)? Dies ist für das automatische Layout vorgesehen, bei dem eine andere Ansicht ein größeres Rahmenrechteck aufweist, wenn das UILabel einen kleineren Text enthält. Gibt es Methoden zum Berechnen dieser Textbreite, wenn ein UIFont und eine Schriftgröße angegeben werden? Es gibt auch keinen Zeilenumbruch und nur eine einzige Zeile.
82
Antworten:
Sie können genau das über die verschiedenen
sizeWithFont:
Methoden in NSString UIKit Additions tun . In Ihrem Fall sollte die einfachste Variante ausreichen (da Sie keine mehrzeiligen Beschriftungen haben):NSString *someString = @"Hello World"; UIFont *yourFont = // [UIFont ...] CGSize stringBoundingBox = [someString sizeWithFont:yourFont];
Es gibt verschiedene Variationen dieser Methode, z. Einige berücksichtigen Zeilenumbruchmodi oder maximale Größen.
quelle
Da
sizeWithFont
es veraltet ist, werde ich nur meine ursprüngliche Antwort auf die Verwendung von Swift 4 und aktualisieren.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) }
Die Größe sollte die Bildschirmgröße von "Ihr Text hier" in Punkten sein.
quelle
sizeWithFont:
ist jetzt veraltet, verwenden SiesizeWithAttributes:
stattdessen:UIFont *font = [UIFont fontWithName:@"Helvetica" size:30]; NSDictionary *userAttributes = @{NSFontAttributeName: font, NSForegroundColorAttributeName: [UIColor blackColor]}; NSString *text = @"hello"; ... const CGSize textSize = [text sizeWithAttributes: userAttributes];
quelle
sizeWithAttributes:
Methode gibt Bruchgrößen zurück. Um eine zurückgegebene Ansicht von Größe zu Größe zu verwenden, müssen Sie ihren Wert mithilfe der Ceil-Funktion auf die nächsthöhere Ganzzahl erhöhen.Update September 2019
Diese Antwort ist eine viel sauberere Methode, um sie mit neuer Syntax zu erstellen.
Ursprüngliche Antwort
Basierend auf Glenn Howes 'hervorragender Antwort habe ich eine Erweiterung erstellt, um die Breite einer Zeichenfolge zu berechnen. Wenn Sie beispielsweise die Breite von a
UISegmentedControl
festlegen, kann dies die Breite basierend auf der Titelzeichenfolge des Segments festlegen.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) } }
Verwendung:
// Set width of segmentedControl let starString = "⭐️" let starWidth = starString.widthOfString(usingFont: UIFont.systemFont(ofSize: 14)) + 16 segmentedController.setWidth(starWidth, forSegmentAt: 3)
quelle
Swift-5
Verwenden Sie intrinsicContentSize, um die Höhe und Breite des Texts zu ermitteln.
yourLabel.intrinsicContentSize.width
Dies funktioniert auch dann, wenn Sie einen benutzerdefinierten Abstand zwischen Ihrer Zeichenfolge haben, z. B. "TEX T".
quelle
Oneliner in Swift 4.2 🔸
let size = text.size(withAttributes:[.font: UIFont.systemFont(ofSize:18.0)])
quelle
Diese einfache Erweiterung in Swift funktioniert gut.
extension String { func size(OfFont font: UIFont) -> CGSize { return (self as NSString).size(attributes: [NSFontAttributeName: font]) } }
Verwendung:
let string = "hello world!" let font = UIFont.systemFont(ofSize: 12) let width = string.size(OfFont: font).width // size: {w: 98.912 h: 14.32}
quelle
Swift 4
extension String { func SizeOf(_ font: UIFont) -> CGSize { return self.size(withAttributes: [NSAttributedStringKey.font: font]) } }
quelle
Dies ist für die schnelle Version 2.3. Sie können die Breite der Zeichenfolge erhalten.
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) }
quelle
Wenn Sie Schwierigkeiten haben, die Textbreite mit mehrzeiliger Unterstützung zu erreichen , können Sie den nächsten Code verwenden ( 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 }
Und auf die gleiche Weise können Sie bei Bedarf die Texthöhe ermitteln (wechseln Sie einfach die ConstraintBox-Implementierung):
let constraintBox = CGSize(width: maxWidth, height: .greatestFiniteMagnitude)
Oder hier ist eine einheitliche Funktion zum Abrufen der Textgröße mit mehrzeiliger Unterstützung:
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 }
Verwendung:
let textSize = labelSize(for: "SomeText", maxWidth: contentView.bounds.width, maxHeight: .greatestFiniteMagnitude) let textHeight = textSize.height.rounded(.up) let textWidth = textSize.width.rounded(.up)
quelle
Für 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; } }
Verwenden Sie es wie ...
let Str = "ABCDEF" let Font = UIFont.systemFontOfSize(19.0) let SizeOfString = Str.SizeOfString(font: Font!)
quelle
Ich bin mir nicht sicher, wie effizient dies ist, aber ich habe diese Funktion geschrieben, die die Punktgröße zurückgibt, die einer Zeichenfolge auf eine bestimmte Breite passt:
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 }
Und es würde so verwendet werden:
textView.font = textView.font!.withSize(textView.text!.fontSizeThatFits(targetWidth: view.frame.width, maxFontSize: 50, font: textView.font!))
quelle
Mein Code besteht darin, eine Erweiterung von UIFont zu erstellen: (Dies ist Swift 4.1)
extension UIFont { public func textWidth(s: String) -> CGFloat { return s.size(withAttributes: [NSAttributedString.Key.font: self]).width } } // extension UIFont
quelle