Ios 在UIlabel中为文本加下划线

Ios 在UIlabel中为文本加下划线,ios,text,uikit,uilabel,underline,Ios,Text,Uikit,Uilabel,Underline,如何为可能是多行字符串的文本加下划线? 我发现有些人建议使用UIWebView,但是对于文本渲染来说,它显然太重了 我的想法是找出每一行中每一根弦的起点和长度。 然后在下面画一条线 我遇到的问题是如何计算字符串的长度和起点 我尝试使用-[UILabel textRectForBounds:LimitedToNumberOfflines:,这应该是文本的图形边界rect,对吗? 那我就得修路线了? 当每一条线都居中对齐且右对齐时,如何获取其起点?您可以从UILabel中创建子类并覆盖drawRec

如何为可能是多行字符串的文本加下划线? 我发现有些人建议使用UIWebView,但是对于文本渲染来说,它显然太重了

我的想法是找出每一行中每一根弦的起点和长度。 然后在下面画一条线

我遇到的问题是如何计算字符串的长度和起点

我尝试使用
-[UILabel textRectForBounds:LimitedToNumberOfflines:
,这应该是文本的图形边界rect,对吗? 那我就得修路线了?
当每一条线都居中对齐且右对齐时,如何获取其起点?

您可以从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];

如果您仍然希望支持iOS4和iOS5,我建议您手动使用而不是下划线标签。但是,如果您需要在一行UILabel下面加下划线,并且不想使用第三方组件,上面的代码仍然可以使用。

正如kovpas所示,您可以在大多数情况下使用边界框,尽管并不总是保证边界框能整齐地围绕文本。高度为50、字体大小为12的框可能无法提供所需的结果,具体取决于UILabel配置

查询UILabel中的UIString以确定其精确度量,并使用这些度量来更好地放置下划线,而不考虑使用kovpas已经提供的图形代码的封闭边界框或框架

您还应该查看UIFont的“leading”属性,该属性根据特定字体给出基线之间的距离。基线是您希望绘制下划线的位置

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

不希望对视图(UILabel/UIButton)进行子类化的人员等。。。 “忘记按钮”也可以用任何标签代替

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

Kovpas代码的增强版(颜色和线条大小)


我已经为多行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]; 
}
-(void)drawRect:(CGRect)rect
{
CGContextRef ctx=UIGraphicsGetCurrentContext();
const CGFloat*colors=CGColorGetComponents(self.textColor.CGColor);
CGContextSetRGBStrokeColor(ctx,颜色[0],颜色[1],颜色[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=高度/线宽;
float totalWidth=[self.text SizeWidthFont:self.font constrainedToSize:CGSizeMake(10009999)].width;

对于(int i=1;i我使用开源的线视图,并将其添加到按钮子视图中:

 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的启发。

使用属性字符串:

NSMutableAttributedString* attrString = [[NSMutableAttributedString alloc] initWithString:@"Your String"]
[attrString addAttribute:(NSString*)kCTUnderlineStyleAttributeName 
                   value:[NSNumber numberWithInt:kCTUnderlineStyleSingle] 
                   range:(NSRange){0,[attrString length]}];
然后覆盖标签-(void)drawTextInRect:(cRect)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);

或者更好的方法是,不使用Olivier Halligon根据Kovpas和Damien Praca的答案创建的,而是使用UILabelUnderAligned的实现,它还支持textAlignemnt

#import <UIKit/UIKit.h>

@interface UILabelUnderlined : UILabel

@end

我结合了一些提供的答案,创建了更好的(至少符合我的需求)UILabel子类,它支持:

  • 具有不同标签边界的多行文本(文本可以在标签框的中间,或者精确的大小)
  • 下划线
  • 三振
  • 下划线/删除线偏移
  • 文本对齐
  • 不同字体大小

这里有另一个更简单的解决方案(下划线的宽度不是最准确的,但对我来说已经足够好了)

我有一个UIView
(\u view\u 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];
}

我就是这么做的,就像黄油一样

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];
迅速:

let underlineAttriString = NSAttributedString(string: "attriString",
                                          attributes: [NSAttributedString.Key.underlineStyle: NSUnderlineStyle.single.rawValue])
label.attributedText = underlineAttriString
另一种解决方案可能是(从iOS 7开始)为
nsbaselineOffsetAttribute Name
指定一个负值,例如您的
nsAttributeString
可能是:

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

希望这会有所帮助;-)

您可以创建一个名为下划线label的自定义标签,并使用编辑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;

可以将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];
Swift 4.1版本:

 let underlineAttriString = NSAttributedString(string:"attriString", attributes:
    [NSAttributedStringKey.underlineStyle: NSUnderlineStyle.styleSingle.rawValue])

label.attributedText = underlineAttriString

有时,我们开发人员会陷入任何UI屏幕的小设计部分。最令人恼火的需求之一是行下文本。不要担心,这里有解决方案

使用Objective C在UILabel中的文本下划线

UILabel *label=[[UILabel alloc]initWithFrame:CGRectMake(0, 0, 320, 480)];
label.backgroundColor=[UIColor lightGrayColor];
NSMutableAttributedString *attributedString;
attributedString = [[NSMutableAttributedString alloc] initWithString:@"Apply Underlining"];
[attributedString addAttribute:NSUnderlineStyleAttributeName value:@1 range:NSMakeRange(0,
[attributedString length])];
[label setAttributedText:attributedString];
使用Swift在UILabel中的文本下划线

 label.backgroundColor = .lightGray
 let attributedString = NSMutableAttributedString.init(string: "Apply UnderLining")
 attributedString.addAttribute(NSUnderlineStyleAttributeName, value: 1, range:
NSRange.init(location: 0, length: attributedString.length))
 label.attributedText = attributedString

你可以使用我的自定义标签! 也可以使用界面生成器设置

import UIKit


class  YHYAttributedLabel : UILabel{
    
    
    @IBInspectable
    var underlineText : String = ""{
        
        didSet{

            self.attributedText = NSAttributedString(string: underlineText,
            attributes: [NSAttributedString.Key.underlineStyle: NSUnderlineStyle.single.rawValue])
        }
        
        
    }

}

我猜这只会为字符串的最后一行画一条下划线,对吗?其他行中的字符串的下划线呢?它不会画多行,但这是我能找到的最好的,所以我猜不可能画多行。我猜我能想到的下一个最好的解决方案是导入一种字体,该字体中内置了下划线字体。这只适用于ios 4.0+,您可以在其中导入字体。您好,我想知道这是否违反了任何ios ui标准。苹果的实现(第二个建议)不支持下线字符?如果我们对UILabel使用NSAttributed字符串支持,对于g、p&q等字母表,下划线将被截断
 let underlineAttriString = NSAttributedString(string:"attriString", attributes:
    [NSAttributedStringKey.underlineStyle: NSUnderlineStyle.styleSingle.rawValue])

label.attributedText = underlineAttriString
UILabel *label=[[UILabel alloc]initWithFrame:CGRectMake(0, 0, 320, 480)];
label.backgroundColor=[UIColor lightGrayColor];
NSMutableAttributedString *attributedString;
attributedString = [[NSMutableAttributedString alloc] initWithString:@"Apply Underlining"];
[attributedString addAttribute:NSUnderlineStyleAttributeName value:@1 range:NSMakeRange(0,
[attributedString length])];
[label setAttributedText:attributedString];
 label.backgroundColor = .lightGray
 let attributedString = NSMutableAttributedString.init(string: "Apply UnderLining")
 attributedString.addAttribute(NSUnderlineStyleAttributeName, value: 1, range:
NSRange.init(location: 0, length: attributedString.length))
 label.attributedText = attributedString
import UIKit


class  YHYAttributedLabel : UILabel{
    
    
    @IBInspectable
    var underlineText : String = ""{
        
        didSet{

            self.attributedText = NSAttributedString(string: underlineText,
            attributes: [NSAttributedString.Key.underlineStyle: NSUnderlineStyle.single.rawValue])
        }
        
        
    }

}