이번 포스팅은 enumerateAttribute라는 메소드를 사용하므로써
NSMutableAttribbutedString에 적용 되어있는 속성을 부분적으로 수정하여
최종적으로 기대한 값과 동일한 Attribute 결과를 도출해내는 과정에 대해 알아보겠다.
예를들어
label에 표현해줄 text 값을 서버에서 내려 받아 설정해준다고 가정을 하겠다.
(html 형태의 String 타입의 값)
아래와 같이 내려온다고 가정 했을때
"<b>12</b> 34 56 <b>78</b>"
html을 변환하는 기본적인 방법을 사용하여 진행해보겠다.
let resultAtt = NSMutableAttributedString()
let data = "<b>12</b> 34 56 <b>78</b>".data(using: .utf8)
let att = try! NSAttributedString(data: data!, options: [.documentType: NSAttributedString.DocumentType.html, .characterEncoding:String.Encoding.utf8.rawValue], documentAttributes: nil)
resultAtt.append(att)
label.attributedText = resultAtt
label text에 표현될 기대값은 12, 78이 bold 처리가 되어있어야 한다.
잘나온다.
이제 폰트를 적용시킬 차례다.
하지만 원하는 폰트를 적용시키려면 해당 부분의 range가 필요하다.
클라이언트 단에서 정적으로 고정하여 표현하는 label의 경우에는 상관이 없지만
지금은 서버에서 응답받은 값을 사용하여 표현하는 케이스이기 때문에
볼드 처리 부분을 동적으로 변경이 되게 로직을 구성해야 한다.
그리하여 enumerateAttribute라는 메소드를 통해
NSMutableAttribbutedString의 설정을 좀더 유하게 변경하는 로직을 발견하게 되었고
force unwrap 이나 컨벤션 같은 작은것들을 수정한 후 프로젝트에 적용시켰다.
NSMutableAttribbutedString에 적용 되어있는 폰트 속성들을 기준으로 enumerate 하여
range 별로 추가적인 수정 작업을 진행 한 로직이다.
private func getAttribute(htmlText: String, withRegularFont regularFont: UIFont, andBoldFont boldFont: UIFont) -> NSMutableAttributedString {
var att = NSMutableAttributedString()
guard let data = htmlText.data(using: .utf8) else { return NSMutableAttributedString() }
do {
att = try NSMutableAttributedString(data: data, options: [.documentType: NSAttributedString.DocumentType.html, .characterEncoding: String.Encoding.utf8.rawValue], documentAttributes: nil)
let range = NSRange(location: 0, length: att.length)
att.enumerateAttribute(.font, in: range, options: .longestEffectiveRangeNotRequired)
{ value, range, _ in
let currentFont: UIFont = (value as? UIFont) ?? .init()
var replacementFont: UIFont?
if currentFont.fontName.contains("bold") || currentFont.fontName.contains("Bold") {
replacementFont = boldFont
} else {
replacementFont = regularFont
}
let replacementAttributeFont = [NSAttributedString.Key.font: replacementFont ?? .init()]
att.addAttributes(replacementAttributeFont, range: range)
}
} catch let error {
print(error.localizedDescription)
}
return att
}
label.attributedText = getAttribute(
htmlText: "<b>12</b> 34 56 <b>78</b>",
withRegularFont: UIFont.systemFont(ofSize: 14, weight: .regular),
andBoldFont: UIFont.systemFont(ofSize: 14, weight: .bold))
enumerate 하여 수정 작업이 진행되고 난 후의 attribute를 보면
의도한 위치(range)에 의도한 속성(font)들이 적용 되어있는것을 볼 수 있을 것이다.
그리고 위에서 사용한 enumerateAttribute 메소드는
폰트뿐만 아니라 다른 attribute 속성들을 기준으로 하여 enumerate를 진행할 수도 있다.
'ISSUE' 카테고리의 다른 글
[ISSUE] Lottie Animation 백그라운드 진입 후 멈춤 현상 (0) | 2021.07.05 |
---|---|
[ISSUE] LaunchScreen 대체 (0) | 2021.01.15 |
[ISSUE] 저전력 모드 화면 꺼짐 방지 (0) | 2021.01.13 |
[ISSUE] AVFoundation ( 3 ) - AVAudioEngine (0) | 2021.01.11 |
[ISSUE] AVFoundation ( 2 ) - AVAudioPlayer (0) | 2021.01.10 |