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

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

진행하고 있는 프로젝트의 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개의 댓글