在UIlabel中加下划线文字

我如何强调可能是多行string的文本? 我发现一些人提出了UIWebView,但是显然只是文本渲染而已。

我的想法是找出每一行中每个string的起点和长度。 并在其下面画一条线。

我遇到了如何计算string长度和起点的问题。 有人可以帮我吗?

我试图使用-[UILabel textRectForBounds:limitedToNumberOfLines:] ,这应该是graphics边界矩形文本权? 那么我必须要alignment? 如何获得每一行的起点,当它是中心和正确的alignment?

我在这里是新的,所以提前谢谢你。

您可以从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为UILabel添加了NSAttributedString支持,所以现在它变得更加简单,适用于多行:

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

如果您仍然希望支持iOS 4和iOS 5,我build议使用TTTAttributedLabel,而不是手动为下划线标签。 但是,如果您需要强调单行UILabel并且不想使用第三方组件,上面的代码仍然可以解决问题。

这就是我所做的。 它像黄油一样工作。

1)将CoreText.framework添加到您的框架。

2)在需要下划线标签的类中导入<CoreText / CoreText.h>。

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

在Swift中:

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

使用属性string:

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

然后重写标签 – (void)drawTextInRect:(CGRect)aRect并将文本渲染成如下forms:

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

或者更好,而不是简单地使用由Olivier Halligon创build的OHAttributedLabel

我已经结合了一些提供的答案,以创build更好的(至less对于我的要求)UILabel子类,它支持:

  • 带有各种标签边界的多行文本(文本可以位于标签框架的中间,或者尺寸准确)
  • 强调
  • 三振出局
  • 下划线/三angular线偏移
  • 文本alignment
  • 不同的字体大小

https://github.com/GuntisTreulands/UnderLineLabel

人们,不希望子类视图(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; } 

另一个解决scheme可能是(自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; 

您可以创build名称为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]; } 

这是最简单的解决scheme,适用于我而无需编写额外的代码。

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

我已创build多线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的框可能不会根据UILabelconfiguration给出所需的结果。

查询UILabel中的UIString以确定其确切的度量标准,并使用这些来更好地放置下划线,而不pipe使用kovpas已经提供的绘图代码的封闭边框或边框。

你也应该看看UIFont的“领先”属性,给出基于特定字体的基线之间的距离。 基线是您希望绘制下划线的位置。

查找添加到NSString的UIKit:

 (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. 

我使用一个开源的线视图,只是将它添加到button子视图:

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

这是上面Karim的启发。

基于Kovpas&Damien Praca的答案,这里是UILabelUnderligned的一个实现,它也支持textAlignemnt

 #import <UIKit/UIKit.h> @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 

这是另一个更简单的解决scheme(下划线的宽度不是最准确的,但对我来说足够好)

我有一个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]; } 

带有NSNumber(其中0不带下划线)的NSUnderlineStyleAttributeName可以添加到属性字典中。 我不知道这是否更容易。 但是,这对我的目的是比较容易的。

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