Aaron
Aaron

Reputation: 619

How do I truncate a string within a string in a UILabel?

Say I have The Dark Knight Rises at 7:45pm and I need to fit that into a fixed-width UILabel (for iPhone). How would I make that truncate as "The Dark Knight Ris... at 7:45pm" rather than "The Dark Knight Rises at 7:4..."?

Upvotes: 4

Views: 6060

Answers (3)

danh
danh

Reputation: 62686

My first idea would be two labels side-by-side both with fixed width, but I'll assume you've ruled that out for some unstated reason. Alternatively, compute the truncation manually, like this ...

- (NSString *)truncatedStringFrom:(NSString *)string toFit:(UILabel *)label
                          atPixel:(CGFloat)pixel atPhrase:(NSString *)substring {

    // truncate the part of string before substring until it fits pixel
    // width in label

    NSArray *components = [string componentsSeparatedByString:substring];
    NSString *firstComponent = [components objectAtIndex:0];
    CGSize size = [firstComponent sizeWithFont:label.font];

    NSString *truncatedFirstComponent = firstComponent;

    while (size.width > pixel) {
        firstComponent = [firstComponent substringToIndex:[firstComponent length] - 1];
        truncatedFirstComponent = [firstComponent stringByAppendingString:@"..."];
        size = [truncatedFirstComponent sizeWithFont:label.font];
    }

    NSArray *newComponents = [NSArray arrayWithObjects:truncatedFirstComponent, [components lastObject], nil];
    return [newComponents componentsJoinedByString:substring];
}

Call it like this:

UILabel *label = [[UILabel alloc] initWithFrame:CGRectMake(0, 0, 160, 21)];
NSString *string = @"The Dark Knight Rises at 7:45pm";
NSString *substring = @"at";
CGFloat pix = 120.0;
NSString *result = [self truncatedStringFrom:string toFit:label atPixel:120.0 atPhrase:@"at"];

label.text = result;

This generates: @"The Dark Kni...at 7:45pm"

Upvotes: 3

Ramy Al Zuhouri
Ramy Al Zuhouri

Reputation: 21966

UILabel has this property:

@property(nonatomic) NSLineBreakMode lineBreakMode;

You enable that behaviour by setting it to NSLineBreakByTruncatingMiddle.

EDIT

I din't understand that you wanted to truncate only a part of the string.Then read this:

If you want to apply the line break mode to only a portion of the text, create a new attributed string with the desired style information and associate it with the label. If you are not using styled text, this property applies to the entire text string in the text property.

Example

So there is even a class for setting the paragraph style: NSParagraphStyle and it has also it's mutable version.
So let's say that you have a range where you want to apply that attribute:

NSRange range=NSMakeRange(i,j);

You have to create a NSMutableParagraphStyle object and set it's lineBreakMode to NSLineBreakByTruncatingMiddle.Notice that you may set also a lot of other parameters.So let's do that:

NSMutableParagraphStyle* style= [NSMutableParagraphStyle new];
style.lineBreakMode= NSLineBreakByTruncatingMiddle;

Then add that attribute for the attributedText of the label in that range.The attributedText property is a NSAttributedString, and not a NSMutableAttributedString, so you'll have to create a NSMutableAttributedString and assign it to that property:

NSMutableAttributedString* str=[[NSMutableAttributedString alloc]initWithString: self.label.text];
[str addAttribute: NSParagraphStyleAttributeName value: style range: range];
self.label.attributedText= str;

Notice that there are a lot of other properties for a NSAttributedString, check here.

Upvotes: 11

Gabriele Petronella
Gabriele Petronella

Reputation: 108101

You have to set the lineBreakMode. You can either do that from Interface Builder or programmatically as follows

label.lineBreakMode = NSLineBreakByTruncatingMiddle;

please note that since iOS 5 the type of such property changed from UILineBreakMode to NSLineBreakMode.

Upvotes: 3

Related Questions