UILabel justifica a izquierda y derecha

Tengo UILabel (marco de cocoa táctil) y quiero justificar a derecha e izquierda su text. como consecuencia estirará el text dentro.

Ejemplo: al igual que si tuviera este text " Mientras se ahorran los costos de fabricación física y envío ", parecería lo siguiente:

"While the saved" "costsof" "physical" "manufacturing" "and shipping" 

como puedes ver la justificación de izquierda y derecha …

¿Cómo puedo lograr eso?

Muchas gracias

  • Lamento haber tenido que hacer las preguntas dobles para publicar la pregunta.

Debería usar mi class OHAttributedLabel .

Tiene todo lo necesario para mostrar un NSAttributedString , que incluye justificar izquierda, centro, derecha … y justificado , y es muy simple de usar.

Puedes encontrarlo aquí en github . Vea el código de muestra provisto que también muestra cómo cambiar la justificación del text.

 // suppose that label is an IBOutlet to an OHAttributedLabel (subclass oh UILabel) label.textAlignment = UITextAlignmentJustify; // and that's all, OHAttributedLabel does everything needed for you! 

(Nota: UITextAlignmentJustify es una constante definida en los encabezados OHAttributedLabel que coincide con la correspondiente constante de CoreText para justificar la alignment. Esta constante no existe en el SDK de Apple)


[EDIT] iOS6 SDK

Desde iOS6 SDK, UITextAlignmentJustify ya no funciona y genera un locking en time de ejecución. Ahora debe configurar la alignment de text de su NSAttributedString en lugar de utilizar la propiedad textAlignment de la label.

Usar UIWebView puede ser lento, así que si eso es un problema, CoreText es el path a seguir.

Aquí hay un código que usa el text central para mostrar una cadena atribuida en una vista. Se sangra un poco como UILabel. Dejé algunas otras opciones de formatting de párrafo para ilustrar cómo puedes establecer otras properties de párrafo y también establecer la cadena atribuida en negrita. Recuerde que necesitará agregar el marco CoreText, de lo contrario obtendrá errores de compilation.

Este código no justifica por completo la última línea. No estoy seguro de que puedas get esto de forma gratuita en CoreText.

el file .h

 // // SmartLabel.h // #import <UIKit/UIKit.h> #import <CoreText/CoreText.h> // needed for CTFontRef, CTFontCreateWithName @interface SmartLabel : UIView { NSMutableAttributedString* _pgSmartString; } @property (nonatomic, retain) NSMutableAttributedString* smartString; - (void) setText: (NSString*) string; - (void) formatString; @end 

Y el file .m

 // // SmartLabel.m // #import "SmartLabel.h" @implementation SmartLabel @synthesize smartString = _pgSmartString; - (void)dealloc { [_pgSmartString release]; [super dealloc]; } - (id)initWithFrame:(CGRect)frame; { if ((self = [super initWithFrame:frame])) { [self setBackgroundColor: [UIColor clearColor]]; } return self; } - (void)drawRect:(CGRect)rect { CGContextRef graphicsContext = UIGraphicsGetCurrentContext(); CGContextSetTextMatrix(graphicsContext, CGAffineTransformIdentity); // turns things right way up CGContextTranslateCTM(graphicsContext, 0, self.bounds.size.height); CGContextScaleCTM(graphicsContext, 1.0, -1.0); CTFramesetterRef framesetter = CTFramesetterCreateWithAttributedString((CFAttributedStringRef)[self smartString]); CGRect bounds = [self bounds]; bounds.origin.x = bounds.origin.x + 8; bounds.size.width = bounds.size.width - 16; CGMutablePathRef path = CGPathCreateMutable(); CGPathAddRect(path, NULL, bounds); CTFrameRef frame = CTFramesetterCreateFrame(framesetter, CFRangeMake(0, [[self smartString] length]), path, NULL); CFRelease(path); CTFrameDraw(frame, graphicsContext); CFRelease(frame); CFRelease(framesetter); } - (void) setText: (NSString*) string; { NSMutableAttributedString* attributedString = [[NSMutableAttributedString alloc] initWithString:string]; [self setSmartString:attributedString]; [attributedString release]; [self formatString]; } - (void) formatString; { CTTextAlignment alignment = kCTJustifiedTextAlignment; // could put different alignments here CGFloat paragraphSpacing = 11.0; CGFloat paragraphSpacingBefore = 0.0; CGFloat firstLineHeadIndent = 0.0; CGFloat headIndent = 0.0; CTParagraphStyleSetting altSettings[] = { { kCTParagraphStyleSpecifierAlignment, sizeof(CTTextAlignment), &alignment}, { kCTParagraphStyleSpecifierFirstLineHeadIndent, sizeof(CGFloat), &firstLineHeadIndent}, { kCTParagraphStyleSpecifierHeadIndent, sizeof(CGFloat), &headIndent}, { kCTParagraphStyleSpecifierParagraphSpacing, sizeof(CGFloat), &paragraphSpacing}, { kCTParagraphStyleSpecifierParagraphSpacingBefore, sizeof(CGFloat), &paragraphSpacingBefore}, }; CTParagraphStyleRef style; style = CTParagraphStyleCreate( altSettings, sizeof(altSettings) / sizeof(CTParagraphStyleSetting) ); if ( style == NULL ) { NSLog(@"*** WARNING *** Unable To Create CTParagraphStyle in apply paragraph formatting" ); return; } [[self smartString] addAttributes:[NSDictionary dictionaryWithObjectsAndKeys:(NSObject*)style,(NSString*) kCTParagraphStyleAttributeName, nil] range:NSMakeRange(0,[[self smartString] length])]; CFRelease(style); UIFont* boldFont = [UIFont boldSystemFontOfSize:12.0]; CTFontRef boldCoreTextFontReference = CTFontCreateWithName ((CFStringRef)[boldFont fontName],[boldFont pointSize], NULL); [[self smartString] addAttributes:[NSDictionary dictionaryWithObjectsAndKeys:(NSObject*)boldCoreTextFontReference,(NSString*) kCTFontAttributeName, nil] range:NSMakeRange(0,[[self smartString] length])]; } @end 

Y para poner en práctica, algo como esto:

 SmartLabel* smartLabel = [[SmartLabel alloc] initWithFrame:CGRectMake(20, 120, 90, 140.0)]; [[self window] addSubview:smartLabel]; [smartLabel setText:@"While the saved costs of physical manufacturing and shipping"]; [smartLabel release]; 

Es muy fácil después del lanzamiento de iOS 6. Usa esto

 //build a style for justification NSMutableParagraphStyle *stringStyle=[[NSMutableParagraphStyle alloc]init]; [stringStyle setAlignment:NSTextAlignmentJustified]; //build a string with the particular paragraph style NSMutableAttributedString* yourString=[[NSMutableAttributedString alloc]init]; [yourString addAttribute:NSParagraphStyleAttributeName value:stringStyle range:NSMakeRange(0, [yourString length])]; //and here you go UILabel *yourLabel; yourlabel.attributedText=yourString; 

Desde iOS 6 puede usar NSMutableAttributedString para esto,

 NSMutableAttributedString* attrStr = [[NSMutableAttributedString alloc] initWithData:[@"Your String value" dataUsingEncoding:NSUTF8StringEncoding] options:@{NSDocumentTypeDocumentAttribute: NSHTMLTextDocumentType, NSCharacterEncodingDocumentAttribute: [NSNumber numberWithInt:NSUTF8StringEncoding]} documentAttributes:nil error:nil]; NSRange rangeOfTitle = NSMakeRange(0,[attrStr length]); [attrStr addAttribute: NSFontAttributeName value:[UIFont fontWithName:@"Calibri" size:19.0]range:rangeOfTitle]; myLabel.attributedText = attrStr; NSMutableParagraphStyle *style = [[NSMutableParagraphStyle alloc] init]; [style setLineSpacing:10]; style.lineBreakMode = NSLineBreakByWordWrapping; style.alignment = NSTextAlignmentJustified; [attrStr addAttribute:NSParagraphStyleAttributeName value:style range:NSMakeRange(0, myLabel.text.length)]; myLabel.attributedText = attrStr; 

La solución perfecta es utilizar NSMutableParagraphStyle

 NSMutableParagraphStyle *paragraphStyles = [[NSMutableParagraphStyle alloc] init]; paragraphStyles.alignment = NSTextAlignmentJustified; //justified text paragraphStyles.firstLineHeadIndent = 1.0; NSDictionary *attributes = @{NSParagraphStyleAttributeName: paragraphStyles}; NSAttributedString *attributedString = [[NSAttributedString alloc] initWithString: YourString attributes: attributes]; YourLabel.attributedText = attributedString; 

Esto se denomina "justificación completa", pero no es compatible con el sistema UILabel (que solo tiene "alineamientos" – izquierda, derecha y centro). Si quieres esto, tendrás que codificarlo tú mismo, creando un control con CoreText o similar.

De acuerdo que esto solo se puede hacer con una buena cantidad de encoding personalizada; que creo que será algo bastante pesado. Antes de entrar en eso; y esto depende de su requerimiento; considera tener una UIWebView donde imagino que podrías administrar styles de text y alineamientos con un poco más de libertad usando alguna encoding HTML y CSS .

Lo siguiente funciona como una solución rápida, pero tenga en count que para algo más que text en negro, necesitará un estilo o CSS.

(De: Alineación justificada en UITextView – iPhone )

He llegado a una solución que funciona. Primero, necesitará cambiar su UITextView y usar una UIWebView en su lugar.

  Details.h @interface Details : UIViewController { IBOutlet UIWebView *descripcion; } @property (nonatomic, retain) UITextView *descripcion; Then, load your UIWebView as follows: Details.m [descripcion loadHTMLString:[NSString stringWithFormat:@"<div align='justify'>%@<div>",YOUR_TEXT] baseURL:nil];