views:

1137

answers:

2

How to underline a text that could be multiple lines of string? I find some people suggest UIWebView, but it is obviously too heave a class for just text rendering.

My thoughts was to figure out the start point and length of each string in each line. And draw a line under it accordingly.

I meet problems at how to figure out the length and start point forthe string. Can anybody help me on this?

I try to use UILable::textRectForBounds, this should be the drawing bounding rect for the text right? Then I have to work on the aligment ? How can I get the start point of each line when it is center-justified and right justfied?

I am new here, so thank in advance.

+1  A: 

You may subclass from UILabel and override drawRect method:

- (void)drawRect:(CGRect)rect {
    CGContextRef ctx = UIGraphicsGetCurrentContext();
    CGContextSetRGBStrokeColor(ctx, 207.0f/255.0f, 91.0f/255.0f, 44.0f/255.0f, 1.0f); // RGBA
    CGContextSetLineWidth(ctx, 1.0f);

    CGContextMoveToPoint(ctx, 0, self.bounds.size.height - 1);
    CGContextAddLineToPoint(ctx, self.bounds.size.width, self.bounds.size.height - 1);

    CGContextStrokePath(ctx);

    [super drawRect:rect];  
}
kovpas
I guess this will only draw one underline for the last line of string, right? What about the underline for the string in other lines?
semix
A: 

As kovpas has shown you can use the bounding box in most cases, although it is not always guaranteed that the bounding box will fit neatly around the text. A box with a height of 50 and font size of 12 may not give the results you want depending on the UILabel configuration.

Query the UIString within the UILabel to determine its exact metrics and use these to better place your underline regardless of the enclosing bounding box or frame using the drawing code already provided by kovpas.

You should also look at UIFont's "leading" property that gives the distance between baselines based on a particular font. The baseline is where you would want your underline to be drawn.

Look up the UIKit additions to NSString:

(CGSize)sizeWithFont:(UIFont *)font 
//Returns the size of the string if it were to be rendered with the specified font on a single line.

(CGSize)sizeWithFont:(UIFont *)font constrainedToSize:(CGSize)size 
// Returns the size of the string if it were rendered and constrained to the specified size.

(CGSize)sizeWithFont:(UIFont *)font constrainedToSize:(CGSize)size lineBreakMode:(UILineBreakMode)lineBreakMode
//Returns the size of the string if it were rendered with the specified constraints.
Kenny
Kennyit seems I can use the 3 methods to get the width of the 1st line of text easily, but how about the 2nd 3rd and other lines?Can you give an example?
semix
I have to concede. There is now way using NSString to achieve what you want, unless someone else has more to offer. I am going to have to suggest like the others before me to use UIWebView and stuff your text into the view:[webView loadHTMLString:@"<html><u>Underlined Text.</u></html>" baseURL:nil];Let it do the layout and determination of where the lines should go.If it is a matter of you want the nth line underlined and you can't know which is the nth line, that is another matter.
Kenny