UITextView에서 특정 문자의 표시 범위를 가져와 강조 표시합니다.

7428 단어 SwiftUITextViewiOS
UITextView에서 다음 방법으로 특정 문자를 표시하는 좌표(CGRect)를 얻을 수 있습니다.
https://developer.apple.com/documentation/uikit/nslayoutmanager/1403255-boundingrect
func boundingRect(forGlyphRange glyphRange: NSRange, in container: NSTextContainer) -> CGRect
이렇게 끝나는 것도 무엇인지, 초록색으로'Qiita'UITextView를 돋보이게 할 준비를 했다.

코드

class TextView: UITextView, UITextViewDelegate {

    // ~~ init() など省略 ~~
    // ~~ delegate に self を ~~

    private func set() {
        let range = (self.text as NSString).range(of: "Qiita")
        var rect = self.layoutManager.boundingRect(forGlyphRange: range, in: self.textContainer)
        rect.origin.x += self.textContainerInset.left
        rect.origin.y += self.textContainerInset.top

        self.viewWithTag(300)?.removeFromSuperview()

        let view = UIView()
        view.backgroundColor = .green
        view.frame = rect
        view.tag = 300
        self.addSubview(view)
        self.sendSubviewToBack(view)
    }

    func textViewDidChange(_ textView: UITextView) {
        set()
    }
}

해설


NSRange 가져오기

Swift.Range<String.Index> 가 아니라 NSRange 을 얻고 싶어서 NSString 먼저 조작합니다.
let range = (self.text as NSString).range(of: "Qiita")

문자열 좌표 CGRect 가져오기


NSRange 범위 내의 문자 textContainer 의 위치를 가져옵니다.
var rect = self.layoutManager.boundingRect(forGlyphRange: range, in: self.textContainer)

inset 분 놓기

UITextView있다textContainerInset. 이 부분에서 벗어났기 때문에 내가 너에게 그 차이를 더해 줄게.
rect.origin.x += self.textContainerInset.left
rect.origin.y += self.textContainerInset.top

하이라이트 UIVIew 추가

UIView의 실례를 생성하고 게재했지만 이 처리는 입력 문자(위 코드에서)마다 실행되기 때문에 필요하지 않은 보기를 포함하여subView도 계속 증가합니다.
따라서 다음 코드로 이전addSubview의 UIVIew를 삭제합니다.
self.viewWithTag(300)?.removeFromSuperview()

기타


아무렇게나 쓴 코드니까 방법을 생각해 보세요.
  • 상기 코드에서 말한 호출set()의 정시
  • Qiita 문자열을 여러 번 입력해도 첫 번째
  • 만 강조표시됩니다.

    환경

  • Swift: 5
  • 좋은 웹페이지 즐겨찾기