Underline text in UIlabel

2019-01-02 15:05发布

How can I underline a text that could be multiple lines of string? I find some people suggest UIWebView, but it is obviously too heavy 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 for the string. Can anybody help me on this?

I tried to use -[UILabel textRectForBounds:limitedToNumberOfLines:], this should be the drawing bounding rect for the text right? Then I have to work on the alignment? How can I get the start point of each line when it is center-justified and right justified?

I am new here, so thank you in advance.

19条回答
若你有天会懂
2楼-- · 2019-01-02 15:35

I've combined some of provided answers, to create better (at least for my requirements) UILabel subclass, which supports:

  • multiline text with various label bounds (text can be in the middle of label frame, or accurate size)
  • underline
  • strikeout
  • underline/strikeout line offset
  • text alignment
  • different font sizes

https://github.com/GuntisTreulands/UnderLineLabel

查看更多
旧人旧事旧时光
3楼-- · 2019-01-02 15:36

An enhanced version of the code of Kovpas (color and line size)

@implementation UILabelUnderlined

- (void)drawRect:(CGRect)rect {

    CGContextRef ctx = UIGraphicsGetCurrentContext();
    const CGFloat* colors = CGColorGetComponents(self.textColor.CGColor);

    CGContextSetRGBStrokeColor(ctx, colors[0], colors[1], colors[2], 1.0); // RGBA

    CGContextSetLineWidth(ctx, 1.0f);

    CGSize tmpSize = [self.text sizeWithFont:self.font constrainedToSize:CGSizeMake(200, 9999)];

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

    CGContextStrokePath(ctx);

    [super drawRect:rect];  
}

@end
查看更多
美炸的是我
4楼-- · 2019-01-02 15:36

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.
查看更多
余生请多指教
5楼-- · 2019-01-02 15:36

NSUnderlineStyleAttributeName which takes an NSNumber (where 0 is no underline) can be added to an attribute dictionary. I don't know if this is any easier. But, it was easier for my purposes.

    NSDictionary *attributes; 
    attributes = @{NSFontAttributeName:font,   NSParagraphStyleAttributeName: style, NSUnderlineStyleAttributeName:[NSNumber numberWithInteger:1]};

    [text drawInRect:CGRectMake(self.contentRect.origin.x, currentY, maximumSize.width, textRect.size.height) withAttributes:attributes];
查看更多
妖精总统
6楼-- · 2019-01-02 15:37

Here is the easiest solution which works for me without writing additional codes.

// To underline text in UILable
NSMutableAttributedString *text = [[NSMutableAttributedString alloc] initWithString:@"Type your text here"];
[text addAttribute:NSUnderlineStyleAttributeName value:@(NSUnderlineStyleSingle) range:NSMakeRange(0, text.length)];
lblText.attributedText = text;
查看更多
无与为乐者.
7楼-- · 2019-01-02 15:38
NSMutableAttributedString *text = [self.myUILabel.attributedText mutableCopy];
[text addAttribute:NSUnderlineStyleAttributeName value:@(NSUnderlineStyleSingle) range:NSMakeRange(0, text.length)];
self.myUILabel.attributedText = text;
查看更多
登录 后发表回答