TTTAttributedLabel을 활용한 iOS 리치 텍스트 렌더링 가이드: 주요 오류 해결 및 활용 팁

iOS 앱 개발에서 사용자 경험을 결정짓는 중요한 요소 중 하나는 텍스트 렌더링입니다. 기본 UILabel은 간단한 텍스트 표시에 적합하지만, 링크 삽입, 특정 단어의 스타일링, 데이터 자동 감지 등 복잡한 요구사항을 충족하기에는 부족함이 있습니다. TTTAttributedLabel은 이러한 한계를 극복하기 위해 설계된 오픈 소스 라이브러리로, UILabel과 완벽하게 호환되면서도 강력한 기능을 제공합니다.

TTTAttributedLabel이 제공하는 핵심 기능

  • 자동 데이터 검출: URL, 전화번호, 주소, 날짜 등을 자동으로 인식하여 링크로 변환합니다.
  • 사용자 정의 링크: 텍스트의 특정 범위(Range)를 지정하여 클릭 가능한 링크를 삽입할 수 있습니다.
  • 고급 스타일링: 링크의 하이라이트 색상, 밑줄 스타일 등을 개별적으로 설정 가능합니다.
  • 세밀한 레이아웃 제어: 행간(Line Spacing), 단락 간격, 수직 정렬 등을 손쉽게 조정합니다.

자주 발생하는 런타임 오류 및 해결 방안

1. attributedText 직접 할당 시 발생하는 크래시

많은 개발자들이 UILabel을 사용하던 방식 그대로 attributedText 속성에 직접 값을 할당하곤 합니다. 하지만 TTTAttributedLabel에서는 이 방식이 내부의 링크 관리 메커니즘을 손상시켜 앱이 예기치 않게 종료되는 원인이 될 수 있습니다.

// 위험한 방법: 크래시가 발생할 수 있음
NSAttributedString *styledString = [[NSAttributedString alloc] initWithString:@"Hello World"];
richLabel.attributedText = styledString;

// 권장되는 방법: setText 메서드 활용
[richLabel setText:styledString];

헤더 파일 명세에 기술된 바와 같이, 반드시 setText: 메서드를 호출해야만 내부 링크 데이터가 정상적으로 갱신됩니다.

2. 링크 클릭 이벤트가 작동하지 않는 경우

텍스트에 링크는 표시되지만 클릭해도 반응이 없다면 다음 세 가지를 확인해야 합니다.

  • delegate 설정 여부
  • userInteractionEnabled 활성화 여부
  • enabledTextCheckingTypes 설정 확인
// 링크 동작을 위한 필수 설정
richLabel.userInteractionEnabled = YES;
richLabel.delegate = self;
richLabel.enabledTextCheckingTypes = NSTextCheckingTypeLink;

3. 텍스트 생략(Truncation) 처리 문제

여러 줄의 텍스트를 표시할 때 끝부분이 잘리는 현상을 커스텀하고 싶다면 attributedTruncationToken을 사용할 수 있습니다.

// 생략 기호 커스터마이징
NSDictionary *tokenAttrs = @{NSForegroundColorAttributeName: [UIColor grayColor]};
NSAttributedString *moreToken = [[NSAttributedString alloc] initWithString:@"...더보기" attributes:tokenAttrs];

richLabel.numberOfLines = 2;
richLabel.lineBreakMode = NSLineBreakByTruncatingTail;
richLabel.attributedTruncationToken = moreToken;

고급 스타일 적용 기법

블록 기반의 복합 스타일링

setText:afterInheritingLabelAttributesAndConfiguringWithBlock: 메서드를 사용하면 기존 라벨의 속성을 유지하면서 특정 부분만 동적으로 스타일링할 수 있습니다.

NSString *content = @"개인정보 처리방침 및 이용약관에 동의합니다.";
[richLabel setText:content afterInheritingLabelAttributesAndConfiguringWithBlock:^NSMutableAttributedString *(NSMutableAttributedString *mutableString) {
    
    // '이용약관' 부분에 굵은 글씨와 색상 적용
    NSRange targetRange = [content rangeOfString:@"이용약관"];
    if (targetRange.location != NSNotFound) {
        UIFont *boldFont = [UIFont boldSystemFontOfSize:15.0f];
        [mutableString addAttribute:NSFontAttributeName value:boldFont range:targetRange];
        [mutableString addAttribute:NSForegroundColorAttributeName value:[UIColor systemRedColor] range:targetRange];
    }
    
    return mutableString;
}];

단락 및 레이아웃 조정

텍스트 내부의 여백이나 줄 간격을 미세하게 조정하여 가독성을 높일 수 있습니다.

// 텍스트 인셋 및 줄 간격 설정
richLabel.textInsets = UIEdgeInsetsMake(8, 12, 8, 12);
richLabel.lineSpacing = 6.0;
richLabel.verticalAlignment = TTTAttributedLabelVerticalAlignmentCenter;

성능 최적화 가이드

리스트(UITableView 등) 내에서 많은 수의 TTTAttributedLabel을 사용하는 경우 성능 이슈가 발생할 수 있습니다. 이를 방지하기 위한 팁은 다음과 같습니다.

  • 필요한 검출기만 활성화: NSTextCheckingTypeLink 등 실제로 필요한 타입만 지정하여 연산량을 줄입니다.
  • 속성 업데이트 최소화: 셀이 재사용될 때 속성을 한 번에 몰아서 변경하는 것이 좋습니다.
  • 사전 계산: 텍스트 높이 계산이 복잡하다면 백그라운드 스레드에서 NSAttributedString을 미리 생성해 두는 방식을 고려하십시오.

Interface Builder 관련 팁

Storyboard나 XIB에서 TTTAttributedLabel을 사용할 때 IB Designables 오류가 발생한다면, 프로젝트 구성 방식에 따라 대응이 필요합니다. use_frameworks!를 사용하는 CocoaPods 환경에서는 동적 프레임워크 임포트가 정상적으로 되었는지 확인하고, 필요시 소스 파일을 직접 프로젝트에 포함하여 렌더링 문제를 해결할 수 있습니다.

태그: iOS TTTAttributedLabel NSAttributedString UIKit Objective-C

7월 18일 16:10에 게시됨