UILabel 텍스트 부분 컬러 변경(근데 이제 RxSwift를 곁들인)

Jee.e (황지희)·2022년 12월 4일

진행하고 있는 프로젝트의 UILabel Text의 일부를 다른 컬러로 변경하고 싶었습니다.
텍스트에 부분적으로 다른 컬러를 적용하는건 아래의 코드와 같이 간단하게 구현이 가능합니다.

let titleLabel: UILabel = {
	let label = UILabel()
    let attributedString = NSMutableAttributedString(string: label.text ?? "")
    attributedString.addAttribute(.foregroundColor, value: UIColor.red, range: (label.text! as NSString).range(of: "부분적으로 색 변경하기"))
    label.attributedText = attributedString
    return label
}()

NSMutableAttributedString 에 전체 텍스트를 넣어주고,
addAttribute 로 변경할 컬러와 범위를 지정해주면 됩니다!


다만, 저는 레이블의 텍스트를 ViewModel에서 주입해주고 있어서 해당 코드가 적용되지 않았습니다.

고민 끝에 ViewController에서 ViewModel의 값을 binding할 때 위 코드를 넣어주면 어떨까? 라는 생각이 들어 실행해보았습니다!


1. ViewModel에서 값을 넣어준다.

struct ViewModel: ViewModelProtocol {
	var title: Driver<String>
    
    init () {
        title = BehaviorRelay<String>(value: "UILabel Text Color 부분적으로 변경하기! 이건 변경할 글씨")
")
            .map { "\($0)" }
            .asDriver(onErrorRecover: { _ in .empty() })
    }
}

2. String을 Extension해서 NSAttributedString을 반환하는 static function을 만든다.

extension String {
    static func changePartialColorInText(_ text: String) -> NSAttributedString? {
        guard !text.isEmpty else { return nil }
        
        let attributeString = NSMutableAttributedString(string: text)
        attributeString.addAttribute(.foregroundColor, value: UIColor.primary, range: (text as NSString).range(of: "이건 변경할 글씨"))
        
        return attributeString
    }
}

3. ViewController의 bind() 메서드에서 위 메서드 적용 및 값 Mapping

   private func bind() {
   		/* ViewModel에서 주입한 Text를 NSAttributedString으로 Mapping 후,
        해당 값을 Label AttributedText에 적용 */
        viewModel.title
            .map { text in
                return String.changePartialColorInText(text)
            }
            .drive(customView.titleLabel.rx.attributedText)
            .disposed(by: disposeBag)
 }

이렇게 하면, 원하는대로 변경 완료!
이미지 제목

profile
교훈없는 경험은 없다고 생각하는 2년차 iOS 개발자입니다.

0개의 댓글