2009-08-24 14 views
41

Tengo un UILabel que muestra algunos caracteres. Como "x", "y" o "rpm". ¿Cómo puedo calcular el ancho del texto en la etiqueta (no indica todo el espacio disponible)? Esto es para el diseño automático, donde otra vista tendrá un rectángulo más grande si UILabel tiene un texto más pequeño dentro. ¿Existen métodos para calcular el ancho del texto cuando se especifica un UIFont y un tamaño de fuente? Tampoco hay salto de línea y solo una línea.¿Cómo calcular el ancho de una cadena de texto de una fuente específica y tamaño de fuente?

+0

No sé cómo podría hacer esto con cualquier tipo de fuente, sin embargo, si está utilizando una fuente de ancho fijo, se puede calcular utilizando el número de caracteres . No estoy del todo seguro de la fórmula. – jgallant

Respuesta

53

Puede hacer exactamente eso a través de los diversos métodos sizeWithFont: en NSString UIKit Additions. En su caso la variante más simple debería ser suficiente (ya que no dispone de etiquetas de múltiples líneas):

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

Hay varias variaciones de este método, por ejemplo. algunos consideran modos de salto de línea o tamaños máximos.

+1

¿No debería ser UIFont * yourFont = // [UIFont ...]; ¿aunque? – PinkFloydRocks

+0

Vaya, sí, claro ... Reparado. –

+7

"sizeWithFont:" está en desuso. La respuesta de wcochran debería ser la marcada. –

39

Desde sizeWithFont es obsoleto, sólo voy a actualizar mi respuesta original a la utilización de Swift 4 y .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) 
} 

El tamaño debe ser el tamaño de la pantalla de "su texto aquí" en puntos.

+0

Gracias por publicar esta solución. Escribí una extensión basada en tu respuesta. Está publicado a continuación. – Adrian

+0

¿Cuál será la función correspondiente en swift 4? – Swayambhu

56

sizeWithFont: ahora es obsoleto, utilice sizeWithAttributes: lugar:

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

Nota: el método 'sizeWithAttributes:' devuelve tamaños fraccionarios; para usar una vista de tamaño devuelto a tamaño, debe elevar su valor al número entero más alto más cercano utilizando la función ceil. – Allen

2

Esto es para SWIFT 2.3 Versión. Puedes obtener el ancho de la cuerda.

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) 
    } 
17

Basado en Glenn Howes' excellent answer, creé una extensión para calcular el ancho de una cadena. Si está haciendo algo como establecer el ancho de UISegmentedControl, esto puede establecer el ancho según la cadena de título del segmento.

extension String { 

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

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

uso:

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

Swift 4

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

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

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

¿Cuál será la solución para swift 4? – Swayambhu

+1

¿Por qué no solo una función que devuelve tamaño (CGSize)? ¿Por qué hacer el trabajo dos veces? – wcochran

+0

@wcochran Actualizado. Gran llamada. – Adrian

3

Este simple extensión en Swift funciona bien.

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

Uso:

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

Para 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; 
    } 
} 

Se usa como ...

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

para SWIFT 4.2

func SizeOf_String(font: UIFont) -> CGSize { 
    let fontAttribute = [NSAttributedStringKey.font: font] 
    let size = self.size(withAttributes: fontAttribute) // for Single Line 
    return size; 
} 
No

probado todavía ...

Cuestiones relacionadas