🌹 어쩌다 이 누추한 곳까지 찾아오셨을까요. 반갑습니다. 🌹

UITextView textAlignment center bug fix!

2020年07月02日

1. 서론

Swift 를 개발하면서 TextView의 textAlignment를 center로 사용해본 적이 없었기 때문에 이 버그를 이번에 처음 봤습니다.

이슈 ticket을 받고 디버그를 찍어보고, playground 에서 demo 프로젝트를 만들면서 이 버그가 기본 버그라는 것을 알게 되었습니다.

버그는 쉽게 볼 수 있습니다.

  
import UIKit
import PlaygroundSupport

class MyViewController : UIViewController {
    override func loadView() {
        let view = UIView()
        view.backgroundColor = .white

        let label = UITextView()
        label.frame = CGRect(x: 150, y: 200, width: 200, height: 200)
        label.textAlignment = .center
        label.textColor = .black
        label.backgroundColor = .brown
        
        view.addSubview(label)


        self.view = view
    }
}

기본 UITextView의 이미지처럼 2줄의 텍스트를 입력하고 1줄에서 줄바꿈을 하면?! 이렇게 cursor 위치가 center 가 아닌 left로 이동합니다.

2. 버그 해결하기

이 버그를 구글링을 하다보면 가장 유명한 (애초에 버그 report가 몇 개 없음) stackoverflow와 같은 해결 방법이 나옵니다.

해결 방법은 앞서 설명한 버그를 실행시키는 경우를 대비하여 작성된 코드인데 현재 상태를 판단해서 중앙으로 cursor 를 위치하게 하는 코드입니다.

이 fix 의 문제는 NSLocationInRange(NSMaxRange(rangeOfCharAfterCaret), fullRange) 를 사용해서 판단하는데 허점이 있습니다.

아래와 같이 입력해보면?

some text(new \n)\n

여러 줄의 텍스트 사이에 줄바꿈을 하는 것이 아닌 끝 줄에서 버그를 발생시키면 다시 버그가 발생됩니다.

그래서 경우의 수를 하나 더 추가해서 해결합니다.

        let isEndOfString = NSMaxRange(rangeOfCharAfterCaret) >= NSMaxRange(fullRange) &&
            text.substring(with: rangeOfCharBeforeCaret) == "\n"
        

3. 전체 소스 코드

전체 코드는 Gist에 올려두었습니다. 😮