2009-08-19 17 views
18

¿Hay algún método para dibujar texto en el medio de un rectángulo? Puedo encontrar varias alineaciones, pero nada de lo que he intentado puede centrar verticalmente el texto en un rect.iPhone - Cómo dibujar texto en medio de un rectángulo

¿Hay un método simple para hacer esto, o hay alguna forma de centrar un rectángulo y luego dibujar en eso?

Estoy dibujando directamente al CGContext, tratando de usar NSString :: drawWithRect o algo similar, ya que realmente no quiero tener que agregar una etiqueta solo para representar texto básico.

Respuesta

29

Bueno, la propiedad font pointSize se corresponde directamente con la altura en píxeles de una NSString dibujado en que UIFont, por lo que su fórmula sería algo como esto:

- (void) drawString: (NSString*) s 
      withFont: (UIFont*) font 
      inRect: (CGRect) contextRect { 

    CGFloat fontHeight = font.pointSize; 
    CGFloat yOffset = (contextRect.size.height - fontHeight)/2.0; 

    CGRect textRect = CGRectMake(0, yOffset, contextRect.size.width, fontHeight); 

    [s drawInRect: textRect 
     withFont: font 
    lineBreakMode: UILineBreakModeClip 
     alignment: UITextAlignmentCenter]; 
} 

UITextAlignmentCenter maneja el centrado horizontal, de manera que usamos el ancho completo del contextRect. El lineBreakMode puede ser lo que quieras.

+0

Esto está muy cerca de lo que eventualmente fui. Gracias – Xetius

+3

De nada. ¿Qué cambiaste, si puedo preguntar? – Amagrammer

+6

Hola, sé que esto es bastante viejo, pero acabo de usarlo y tuve que hacer un cambio. Mi cambio fue la línea CGRect textRect .... Lo cambié a ... CGRect textRect = CGRectMake (contextRect.origin.x, contextRect.origin.y + yOffSet, contextRect.size.width, fontHeight); – Fogmeister

2

En iOS 6 obtiene cadenas atribuidas y alineaciones de párrafo, por lo que esto se vuelve mucho más directo y poderoso. En este ejemplo se dibuja un gran "A" roja en el centro de un rectángulo:

NSMutableParagraphStyle* p = [NSMutableParagraphStyle new]; 
p.alignment = NSTextAlignmentCenter; 
NSAttributedString* bigA = 
    [[NSAttributedString alloc] initWithString:@"A" attributes:@{ 
     NSFontAttributeName: [UIFont fontWithName:@"Georgia" size:100], 
     NSForegroundColorAttributeName: [UIColor redColor], 
     NSParagraphStyleAttributeName: p 
    }]; 
[bigA drawInRect:CGRectMake(0,0,200,200)]; 
+3

Eso centra el texto horizontalmente, pero no lo alinea verticalmente. – Clay

+0

"Alinear verticalmente"? Solo sácalo donde quieras. O dibuja algo (por ejemplo, una imagen) y ponlo donde quieras. – matt

+8

Derecha - Entiendo lo que dices. Solo estaba tratando de señalar que creo que la pregunta era cómo alinear algo verticalmente en el centro de algo más grande. Dado un 'NSRect' predeterminado, por ejemplo, ¿cómo se puede usar' [myString drawInRect: myRect] 'o una variante para colocar la cadena en el centro vertical de' myRect'. Para Cocoa, lo hago incluyendo la categoría 'NS (Atribución) String + Geometrics' de https://github.com/jerrykrinock/CategoriesObjC y haciendo un poco de matemática simple con' - (float) heightForWidth: (float) método de ancho – Clay

1

estoy de acuerdo con la respuesta de amagrammer, a excepción de un pequeño cambio: Consumo font.lineSize para obtener la altura adecuada. Asumo que sizeWithFont le dará los LINESIZE así

+0

Estoy de acuerdo contigo, pero lineSize o lineHeight? – damithH

0

he encontrado este código funciona bastante bien:

NSString *text = @"A bit of text to draw"; 
UIFont *font = [UIFont systemFontOfSize:12]; 
CGRect textFrame = (CGRect) 
{ 
    .size.width = 150, 
    .size.height = 150, 
}; 
CGSize textSize = [text sizeWithFont:font constrainedToSize:textFrame.size lineBreakMode:NSLineBreakByWordWrapping]; 
CGRect newTextFrame = CGRectInset(textFrame, 0, (textFrame.size.height - textSize.height)/2); 
[text drawInRect:newTextFrame withFont:font lineBreakMode:NSLineBreakByWordWrapping alignment:NSTextAlignmentCenter]; 

El texto, la fuente y que contiene el marco puede venir de cualquier parte, por lo que sólo tiene que utilizar la misma línea modo de corte cuando haces el cálculo y el dibujo.

17

Aquí hay una versión actualizada para iOS7.0 +.

También he mejorado la respuesta anterior utilizando el método sizeWithAttributes: que devuelve los límites del texto, lo que le permite colocar correctamente el texto antes de dibujarlo. Esto elimina la necesidad de codificar cualquier ajuste que se romperá si usa una fuente de diferente tamaño o si usa una fuente diferente.

- (void) drawString: (NSString*) s 
      withFont: (UIFont*) font 
      inRect: (CGRect) contextRect { 

    /// Make a copy of the default paragraph style 
    NSMutableParagraphStyle *paragraphStyle = [[NSParagraphStyle defaultParagraphStyle] mutableCopy]; 
    /// Set line break mode 
    paragraphStyle.lineBreakMode = NSLineBreakByTruncatingTail; 
    /// Set text alignment 
    paragraphStyle.alignment = NSTextAlignmentCenter; 

    NSDictionary *attributes = @{ NSFontAttributeName: font, 
            NSForegroundColorAttributeName: [UIColor whiteColor], 
            NSParagraphStyleAttributeName: paragraphStyle }; 

    CGSize size = [s sizeWithAttributes:attributes]; 

    CGRect textRect = CGRectMake(contextRect.origin.x + floorf((contextRect.size.width - size.width)/2), 
           contextRect.origin.y + floorf((contextRect.size.height - size.height)/2), 
           size.width, 
           size.height); 

    [s drawInRect:textRect withAttributes:attributes]; 
} 
Cuestiones relacionadas