[ios] UIlabel의 밑줄 텍스트

여러 줄의 문자열이 될 수있는 텍스트에 어떻게 밑줄을 긋을 수 있습니까? 어떤 사람들은 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];
}

UPD :
iOS 6부터 Apple은 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을 사용하는 것이 좋습니다.


답변

나는 더 나은 (적어도 내 요구 사항에 대해) UILabel 하위 클래스를 만들기 위해 제공된 답변 중 일부를 결합했습니다.

  • 다양한 레이블 경계가있는 여러 줄 문자 (문자는 레이블 프레임의 중간 또는 정확한 크기에있을 수 있음)
  • 밑줄
  • 삼진
  • 밑줄 / 취소 선 간격 띄우기
  • 텍스트 정렬
  • 다양한 글꼴 크기

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