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

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

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

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

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

Я здесь новый, так что спасибо заранее.

    Вы можете подclassы из 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 и не хотите использовать сторонние компоненты, код выше все равно будет делать трюк.

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

    1) Добавьте CoreText.framework в свои Framework.

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

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

    В Свифт:

      let underlineAttriString = NSAttributedString(string:"attriString", attributes: [NSUnderlineStyleAttributeName: NSUnderlineStyle.StyleSingle.rawValue]) label.attributedText = underlineAttriString 

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

     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, созданный Оливье Хэллигоном

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

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

    https://github.com/GuntisTreulands/UnderLineLabel

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

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

    Другим решением может быть (начиная с 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)}]; 

    Надеюсь, это поможет 😉

     NSMutableAttributedString *text = [self.myUILabel.attributedText mutableCopy]; [text addAttribute:NSUnderlineStyleAttributeName value:@(NSUnderlineStyleSingle) range:NSMakeRange(0, text.length)]; self.myUILabel.attributedText = text; 

    Вы можете создать пользовательскую метку с именем UnderlinedLabel и отредактировать функцию drawRect.

     #import "UnderlinedLabel.h" @implementation UnderlinedLabel - (void)drawRect:(CGRect)rect { NSString *normalTex = self.text; NSDictionary *underlineAttribute = @{NSUnderlineStyleAttributeName: @(NSUnderlineStyleSingle)}; self.attributedText = [[NSAttributedString alloc] initWithString:normalTex attributes:underlineAttribute]; [super drawRect:rect]; } 

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

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

    Расширенная версия кода Kovpas (цвет и размер строки)

     @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 

    Я создал для многострочного uilabel с подчеркиванием:

    Для размера шрифта от 8 до 13 установите int lineHeight = self.font.pointSize + 3;

    Для размера шрифта от 14 до 20 установите int lineHeight = self.font.pointSize + 4;

     - (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(self.frame.size.width, 9999)]; int height = tmpSize.height; int lineHeight = self.font.pointSize+4; int maxCount = height/lineHeight; float totalWidth = [self.text sizeWithFont:self.font constrainedToSize:CGSizeMake(1000, 9999)].width; for(int i=1;i<=maxCount;i++) { float width=0.0; if((i*self.frame.size.width-totalWidth)<=0) width = self.frame.size.width; else width = self.frame.size.width - (i* self.frame.size.width - totalWidth); CGContextMoveToPoint(ctx, 0, lineHeight*i-1); CGContextAddLineToPoint(ctx, width, lineHeight*i-1); } CGContextStrokePath(ctx); [super drawRect:rect]; } 

    Как показал kovpas, вы можете использовать ограничительную рамку в большинстве случаев, хотя не всегда гарантируется, что ограничивающая рамка будет аккуратно размещаться вокруг текста. Коробка с высотой 50 и размером шрифта 12 может не дать желаемых результатов в зависимости от конфигурации UILabel.

    Запросите UIString в UILabel, чтобы определить его точные показатели и использовать их, чтобы лучше разместить подчеркивание независимо от охватывающей ограничивающей frameworks или фрейма, используя код чертежа, уже предоставленный kovpas.

    Вы также должны посмотреть на «ведущее» свойство UIFont, которое дает расстояние между базовыми линиями, основанными на определенном шрифте. Базовый уровень – это то, где вы хотите, чтобы ваше подчеркивание было нарисовано.

    Просмотрите дополнения UIKit к 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. 

    Я использую представление с открытым исходным кодом и просто добавил его в подпункт кнопки:

      UILabel *label = termsButton.titleLabel; CGRect frame = label.frame; frame.origin.y += frame.size.height - 1; frame.size.height = 1; SSLineView *line = [[SSLineView alloc] initWithFrame:frame]; line.lineColor = [UIColor lightGrayColor]; [termsButton addSubview:line]; 

    Это было вдохновлено Карим выше.

    Основываясь на ответах Kovpas & Damien Praca, здесь представлена ​​реализация UILabelUnderligned, которая также поддерживает textAlignemnt .

     #import  @interface UILabelUnderlined : UILabel @end 

    и реализация:

     #import "UILabelUnderlined.h" @implementation DKUILabel - (id)initWithFrame:(CGRect)frame { self = [super initWithFrame:frame]; if (self) { // Initialization code } return self; } - (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 textSize = [self.text sizeWithFont:self.font constrainedToSize:CGSizeMake(200, 9999)]; // handle textAlignement int alignementXOffset = 0; switch (self.textAlignment) { case UITextAlignmentLeft: break; case UITextAlignmentCenter: alignementXOffset = (self.frame.size.width - textSize.width)/2; break; case UITextAlignmentRight: alignementXOffset = self.frame.size.width - textSize.width; break; } CGContextMoveToPoint(ctx, alignementXOffset, self.bounds.size.height - 1); CGContextAddLineToPoint(ctx, alignementXOffset+textSize.width, self.bounds.size.height - 1); CGContextStrokePath(ctx); [super drawRect:rect]; } @end 

    Вот еще одно, более простое решение (ширина подчеркивания не самая точная, но для меня это было достаточно хорошо)

    У меня есть UIView (_view_underline) который имеет белый фон, высоту 1 пиксель, и я обновляю его ширину каждый раз, когда я обновляю текст

     // It's a shame you have to do custom stuff to underline text - (void) underline { float width = [[_txt_title text] length] * 10.0f; CGRect prev_frame = [_view_underline frame]; prev_frame.size.width = width; [_view_underline setFrame:prev_frame]; } 

    NSUnderlineStyleAttributeName, которое принимает NSNumber (где 0 не является подчеркиванием), может быть добавлено в словарь атрибутов. Я не знаю, легче ли это. Но это было легче для моих целей.

      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]; 
    Interesting Posts

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

    Как сжатие NTFS влияет на производительность?

    Синий экран смерти только после игры Counter Strike 1.6

    Спекуляция для JUnit XML Output

    Не может быть папка Acess на внешнем жестком диске HD

    Как узнать, из какой программы поступает сигнал по умолчанию в Windows 7?

    Проблема маршрутизации с мостовым соединением

    Могут ли старые жетоны GCM жить даже после удаления?

    Отслеживание проблемы утечки памяти / сборки мусора в Java

    Как отделить знаки доллара ($) от данных / исключить специальные символы в R?

    Windows задерживает логин после неудачных попыток пары

    Можем ли мы увеличить повторное использование этой ключевой схемы защиты доступа?

    Должны ли вы когда-либо использовать защищенные переменные-члены?

    В чем разница между портом и сокетом?

    Что такое JAVA_HOME? Как JVM находит путь javac, хранящийся в JAVA_HOME?

    Давайте будем гением компьютера.