如何为可能跨越多行的文本添加下划线呢?
有些人建议使用UIWebView,但仅用于文本渲染显然太重了。
我的想法是找出每行每个字符串的起始点和长度,并相应地在下面画一条线。
我遇到的问题是如何找出字符串的长度和起始点。
我尝试使用-[UILabel textRectForBounds:limitedToNumberOfLines:]
,这应该是文本的绘制边界矩形,对吗?
然后我还需要处理对齐方式?
当它居中对齐和右对齐时,如何获取每行字符串的起始点?
你可以从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];
}
更新:
自iOS 6起,苹果公司为UILabel添加了NSAttributedString支持,因此现在它更容易处理多行文本:
NSDictionary *underlineAttribute = @{NSUnderlineStyleAttributeName: @(NSUnderlineStyleSingle)};
myLabel.attributedText = [[NSAttributedString alloc] initWithString:@"Test string"
attributes:underlineAttribute];
如果你想支持iOS 4和iOS 5,我建议使用TTTAttributedLabel来代替手动下划线标签。但是如果你需要给单行UILabel添加下划线而又不想使用第三方组件,上面的代码仍然可以实现。在Swift中:
let underlineAttriString = NSAttributedString(string: "attriString",
attributes: [NSAttributedString.Key.underlineStyle: NSUnderlineStyle.single.rawValue])
label.attributedText = underlineAttriString
这是我所做的。它像黄油一样运行。
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];
使用属性字符串:
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);
或者更好的方法是,不要覆盖原有的内容,而是使用由Olivier Halligon创建的OHAttributedLabel
NSMutableAttributedString
- borrrden我结合了提供的一些答案,创建了一个更好的(至少对我的要求来说更好)UILabel子类,支持以下功能:
不想继承视图(如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;
}
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;
#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];
}