Подчеркните текст в UIlabel - PullRequest
       133

Подчеркните текст в UIlabel

81 голосов
/ 26 апреля 2010

Как я могу подчеркнуть текст, который может состоять из нескольких строк? Я считаю, что некоторые люди предлагают UIWebView, но это явно слишком тяжелый класс для простого рендеринга текста.

Я думал о том, чтобы выяснить начальную точку и длину каждой строки в каждой строке. И нарисуйте линию под ним соответственно.

У меня возникают проблемы с определением длины и начальной точки строки.

Я пытался использовать -[UILabel textRectForBounds:limitedToNumberOfLines:], это должен быть ограничивающий прямоугольник для текста, верно? Тогда я должен работать над выравниванием? Как я могу получить начальную точку каждой линии, если она выровнена по центру и выровнена по правому краю?

Ответы [ 19 ]

134 голосов
/ 26 апреля 2010

Вы можете создать подкласс UILabel и переопределить метод drawRect:

- (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];  
}

UPD:
Начиная с iOS 6 Apple добавила поддержку NSAttributedString для UILabel, так что теперь это намного проще и работает для нескольких строк:

NSDictionary *underlineAttribute = @{NSUnderlineStyleAttributeName: @(NSUnderlineStyleSingle)};
myLabel.attributedText = [[NSAttributedString alloc] initWithString:@"Test string" 
                                                         attributes:underlineAttribute];

Если вы по-прежнему хотите поддерживать iOS 4 и iOS 5, я рекомендую использовать TTTAttributedLabel вместо подчеркивания метки вручную. Однако, если вам нужно подчеркнуть UILabel в одну строку и вы не хотите использовать сторонние компоненты, приведенный выше код все равно поможет.

37 голосов
/ 28 октября 2013

Это то, что я сделал. Это работает как масло.

1) Добавьте CoreText.framework в свои фреймворки.

2) импортируйте в класс, где требуется подчеркнутая метка.

3) Введите следующий код.

    NSMutableAttributedString *attString = [[NSMutableAttributedString alloc] initWithString:@"My Messages"];
    [attString addAttribute:(NSString*)kCTUnderlineStyleAttributeName
              value:[NSNumber numberWithInt:kCTUnderlineStyleSingle]
              range:(NSRange){0,[attString length]}];
    self.myMsgLBL.attributedText = attString;
    self.myMsgLBL.textColor = [UIColor whiteColor];
34 голосов
/ 22 ноября 2014

В Свифт:

let underlineAttriString = NSAttributedString(string: "attriString",
                                          attributes: [NSAttributedString.Key.underlineStyle: NSUnderlineStyle.single.rawValue])
label.attributedText = underlineAttriString
19 голосов
/ 11 апреля 2012

Использовать строку атрибута:

NSMutableAttributedString* attrString = [[NSMutableAttributedString alloc] initWithString:@"Your String"]
[attrString addAttribute:(NSString*)kCTUnderlineStyleAttributeName 
                   value:[NSNumber numberWithInt:kCTUnderlineStyleSingle] 
                   range:(NSRange){0,[attrString length]}];

А затем переопределить метку - (void) drawTextInRect: (CGRect) aRect и отобразить текст примерно так:

CGContextRef ctx = UIGraphicsGetCurrentContext();
CGContextSaveGState(ctx);
CTFramesetterRef framesetter = CTFramesetterCreateWithAttributedString((CFAttributedStringRef)attrString);
drawingRect = self.bounds;
CGMutablePathRef path = CGPathCreateMutable();
CGPathAddRect(path, NULL, drawingRect);
textFrame = CTFramesetterCreateFrame(framesetter,CFRangeMake(0,0), path, NULL);
CGPathRelease(path);
CFRelease(framesetter);
CTFrameDraw(textFrame, ctx);
CGContextRestoreGState(ctx);

Или, что еще лучше, вместо переопределения, просто используйте OHAttributedLabel , созданный Оливье Халлигоном

15 голосов
/ 06 августа 2012

Я объединил некоторые из предоставленных ответов, чтобы создать лучший (по крайней мере, для моих требований) подкласс UILabel, который поддерживает:

  • многострочный текст с различными границами надписей (текст может быть посередине рамки надписи или точного размера)
  • Подчеркивание
  • вычеркнуто
  • смещение подчеркивания / вычеркивания
  • выравнивание текста
  • разные размеры шрифта

https://github.com/GuntisTreulands/UnderLineLabel

11 голосов
/ 11 января 2011

Люди, которые не хотят создавать подклассы представления (UILabel / UIButton) и т. Д. «ForgotButton» можно заменить на любой ярлык.

-(void) drawUnderlinedLabel {
    NSString *string = [forgetButton titleForState:UIControlStateNormal];
    CGSize stringSize = [string sizeWithFont:forgetButton.titleLabel.font];
    CGRect buttonFrame = forgetButton.frame;
    CGRect labelFrame = CGRectMake(buttonFrame.origin.x + buttonFrame.size.width - stringSize.width, 
            buttonFrame.origin.y + stringSize.height + 1 , 
            stringSize.width, 2);
    UILabel *lineLabel = [[UILabel alloc] initWithFrame:labelFrame];
    lineLabel.backgroundColor = [UIColor blackColor];
    //[forgetButton addSubview:lineLabel];
    [self.view addSubview:lineLabel];
}
8 голосов
/ 20 февраля 2013
NSString *tem =self.detailCustomerCRMCaseLabel.text;
if (tem != nil && ![tem isEqualToString:@""]) {
    NSMutableAttributedString *temString=[[NSMutableAttributedString alloc]initWithString:tem];
    [temString addAttribute:NSUnderlineStyleAttributeName
                      value:[NSNumber numberWithInt:1]
                      range:(NSRange){0,[temString length]}];
    self.detailCustomerCRMCaseLabel.attributedText = temString;
}
7 голосов
/ 11 апреля 2016
NSMutableAttributedString *text = [self.myUILabel.attributedText mutableCopy];
[text addAttribute:NSUnderlineStyleAttributeName value:@(NSUnderlineStyleSingle) range:NSMakeRange(0, text.length)];
self.myUILabel.attributedText = text;
7 голосов
/ 21 апреля 2015

Другим решением может быть (начиная с iOS 7) задание отрицательного значения для NSBaselineOffsetAttributeName, например, ваше NSAttributedString может быть:

NSAttributedString *attributedText = [[NSAttributedString alloc] initWithString:@"my text goes here'
                                                            attributes:@{NSFontAttributeName: [UIFont fontWithName:@"Helvetica-Regular" size:12],
                                                                         NSForegroundColorAttributeName: [UIColor blackColor],
                                                                         NSUnderlineStyleAttributeName: @(NSUnderlineStyleSingle), NSBaselineOffsetAttributeName: @(-3)}];

Надеюсь, это поможет; -)

3 голосов
/ 06 октября 2016

Вот самое простое решение, которое работает для меня без написания дополнительных кодов.

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