진행 중이던 프로젝트에서 해시태그 기능을 작업했다.
일단 내가 원하는 기능은 해시태그끼리 붙여놔도 잘 작동되기, 한글 인식하기 정도였는데 마침 어떤 개발자 분의 블로그에 좋은 코드가 있어서 참고를 했다.
import UIKit
// 한글, 영문, 숫자만 가능
class HashtagTextView: UITextView {
var hashtagArr: [String]?
func resolveHashTags() {
self.isEditable = false
self.isSelectable = true
let nsText: NSString = self.text as NSString
let attrString = NSMutableAttributedString(string: nsText as String)
let hashtagDetector = try? NSRegularExpression(pattern: "#(\\w+)", options: NSRegularExpression.Options.caseInsensitive)
let results = hashtagDetector?.matches(in: self.text,
options: NSRegularExpression.MatchingOptions.withoutAnchoringBounds,
range: NSMakeRange(0, self.text.utf16.count))
hashtagArr = results?.map{ (self.text as NSString).substring(with: $0.range(at: 1)) }
if hashtagArr?.count != 0 {
var i = 0
for var word in hashtagArr! {
word = "#" + word
if word.hasPrefix("#") {
let matchRange:NSRange = nsText.range(of: word as String, options: .caseInsensitive)
attrString.addAttribute(NSAttributedString.Key.link, value: "\(i)", range: matchRange)
i += 1
}
}
}
self.attributedText = attrString
}
}
간단하게 코드 설명을 하자면 글 내용에서 #으로 시작하는 글자가 있을 때, # 단위로 끊어서 한글 인식이 되도록 인코딩을 해주었고 인코딩 된 단어를 배열에 집어넣었다.
그리고 반복문을 돌려서 글 내용에 배열에 넣었던 단어가 포함되어 있을 경우
addAttribute(NSAttributedString.Key.link, value:, range:)를 써서 태그 된 단어에 링크 속성이 적용되도록 만들었다.
한글 인식도 잘 되고
해시태그끼리 붙여서 써도 아주 잘 된다
그런데... 발생한 문제
중복된 글자는 링크 처리가 안 된다...
그래서 어떤 부분이 문제인가 봤더니
let matchRange:NSRange = nsText.range(of: word as String, options: .caseInsensitive)
attrString.addAttribute(NSAttributedString.Key.link, value: "\(i)", range: matchRange)
range 함수 옵션 부분을 보면 caseInsensitive라고 되어있다.
이 옵션은 텍스트뷰 안에서 대소문자를 구분하지 않고, 맨 처음부터(중요함) 일치하는 단어가 있는지 찾는 옵션이다.
앞에서 #한글이라는 단어를 찾을 때 이미 첫 부분에 #한글로 라는 태그가 있기 때문에 이걸로 인식해버리는 것...
그래서 옵션을 backwards(맨 뒤에서부터 검색하는 옵션) 이걸로 바꿔보기도 하며(그래도 안 됐다) 수많은 삽질을 반복했고
결론은... 성공했다!
찾아보니까 옵션을 배열로 처리해서 두 가지 속성을 집어넣는 방법이 있었다.
코드는 이렇게 수정했다. 앞에서부터 찾고, 뒤에서부터도 찾는 방식
let matchRange:NSRange = nsText.range(of: word as String, options: [.caseInsensitive, .backwards])
이렇게 잘 나오는 걸 확인할 수 있다!
참고한 사이트는 밑에
'삽질기' 카테고리의 다른 글
[iOS] extension에서 Override하기 (1) | 2021.03.09 |
---|---|
[iOS] 불필요한 서버 호출 코드 수정하기 (1) | 2021.03.07 |