Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

UILabel justify left and right

i have UILabel (cocoa touch framework) and i want to right and left justify its text. as a consequence it will stretch the text inside.

Example: like if i had this text "While the saved costs of physical manufacturing and shipping" it would appear like the following:

"While the saved"
"c o s t s   o f"
"p h y s i c a l"
 "manufacturing"
"a n d  shipping"

as you can see left and right justification...

how can i achieve that ???

many thanks

  • i'm sorry i had to put the double qoutations to post the question.
like image 452
M.Saleh Avatar asked Sep 11 '11 13:09

M.Saleh


2 Answers

You should use my OHAttributedLabel class.

It has everything needed to display an NSAttributedString, including justifying left, center, right… and justified, and is really simple to use.

You can find it here on github. See the sample code provided that also shows how to change text justification.

// 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!

(Note: UITextAlignmentJustify is a constant defined in OHAttributedLabel headers that matches corresponding CoreText constant for justify alignment. This constant does not exists in Apple's SDK)


[EDIT] iOS6 SDK

Since iOS6 SDK, the UITextAlignmentJustify does not work anymore and generate a crash at runtime. Now you should set the text alignment of your NSAttributedString itself instead of using the textAlignment property of the label.

like image 69
AliSoftware Avatar answered Oct 30 '22 16:10

AliSoftware


Using UIWebView can be slow, so if that's an issue CoreText is the way to go.

Here's some code that uses core text to display an attributed string on a view. It indents a bit like UILabel. I've left some other paragraph formatting options in to illustrate how you can set other paragraph properties and also set the attributed string to bold. Remember you'll need to add the CoreText framework otherwise you'll get build errors.

This code doesn't full justify the last line. Not sure you can get this for free in CoreText.

the .h file

//
//  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

And the .m file

//
//  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

And to put to use, something like this:

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];
like image 29
Obliquely Avatar answered Oct 30 '22 16:10

Obliquely