본문 바로가기

SwiftUI

[SwiftUI] 텍스트 에디터에 글자수 제한을 둬보자!

728x90

SwiftUI에서는 사용자에게 입력을 받기 위해서 'TextField' 또는 'TextEditor'를 사용할 수 있다.

 

UIKit의 UITextField -> TextField

UITextView -> TextEditor로 각각 마이그레이션 되었다.

 

애플 공식 다큐먼트의 TextEditor에 대한 내용

위의 문서 내용처럼 TextEditor는 사용자에게 긴 입력을 받을때 사용하는 View이다. iOS 14에서부터 사용이 가능한걸 보아하니 SwiftUI에 도입된지 얼마 안된 따끈따끈한 뷰라고 볼 수 있다.

 

그런데, 개발중에 텍스트 에디터를 통해 제한된 입력을 받아야하는 경우가 생겼다.

즉, 자소서를 입력할 때처럼 500자, 1000자 제한등이 필요한 경우가 있는데 기존의 UIKit에서는 관련 자료가 방대했지만, TextEditor의 경우에는 자료가 많지 않아 직접 찾아 구현해 보았다.

 

기본적인 TextEditor의 사용법

 

위처럼 500자 제한을 주려고 할때, onChange를 통해 description의 변화값을 받아서 조건문으로 분기하면 되겠다고 생각했다.

 

            TextEditor(text: $description)
                .lineSpacing(5)
                .frame(maxWidth: .infinity, minHeight: 300)
                .padding(EdgeInsets(top: 10, leading: 10, bottom: 10, trailing: 10))
                .background(.white)
                .onChange(of: description) { desc in
                    if desc.count > 10 { // 제한할 글자수
                        DispatchQueue.main.async {
                            self.description = String(desc.prefix(10)) // 제한할 글자수
                        }
                    }
                }

 

그래서 위처럼 구현해줬다. 그런데 여기서 DispatchQueue.main.async 블록으로 감싸주지 않으면 사용자가 빠른 속도로 입력을 했을때, SwiftUI의 뷰를 다시 그리는 주기와 맞물려서 에러 메시지가 출력이 되는 경우가 발생했다.

따라서, 뷰는 메인 쓰레드에서 그려주기 때문에 GCD 블록으로 감싸주었다.

 

그런데, 여기서의 문제는 현재 사용자가 입력한 글자수가  표시를 안해주고 있다. 관련 Text를 overlay로 표시해 주기로 했다.

(참고로, 위의 제한할 글자수를 별도의 constant로 만들어 관리해주면 좋을 것 같다!!)

 

TextEditor(text: $description)
                .lineSpacing(5)
                .frame(maxWidth: .infinity, minHeight: 300)
                .padding(EdgeInsets(top: 10, leading: 10, bottom: 10, trailing: 10))
                .background(.white)
                .onChange(of: description) { desc in
                    if desc.count > 500 {
                        DispatchQueue.main.async {
                            self.description = String(desc.prefix(500))
                        }
                    }
                }
                .overlay(
                    Text("\(description.count)/500")
                        .font(.system(size: 13))
                        .foregroundColor(.gray)
                        .padding(), alignment: .bottomTrailing
                )

 

글자수를 제한한 화면

위와같이 SwiftUI의 TextEditor에서도 제한된 글자수를 입력받게하는 방법을 알아보았다.

(난 야스오 장인이다.)

이상 끝~