진행하고 있는 프로젝트의 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할 때 위 코드를 넣어주면 어떨까?
라는 생각이 들어 실행해보았습니다!
struct ViewModel: ViewModelProtocol {
var title: Driver<String>
init () {
title = BehaviorRelay<String>(value: "UILabel Text Color 부분적으로 변경하기! 이건 변경할 글씨")
")
.map { "\($0)" }
.asDriver(onErrorRecover: { _ in .empty() })
}
}
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
}
}
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)
}
이렇게 하면, 원하는대로 변경 완료!