이번에는 텍스트 필드의 글자수를 제한하여 UI가 변경되는 것을 방지하였습니다.
간단한 기능이라고 생각하고 미루다가 작업을 해보았는데.. 생각보다 쉽지만은 않았습니다.
1. View 혹은 SearchBar의 Frame(height:)에 값을 주는 방법으로는 해결되지 않았습니다.
2. 구글링하여 didSet, onChange, onReceive 등의 자료들을 찾아보았지만 작동하지 않았습니다.
didSet은 xCode13+에서 해당 문제를 해결할 수 없다는 의견이었고, onChange와 onReceive는 작동하지 않았습니다.
ViewModel에 있는 @Published var searchText: String = "" 변수의 글자 수를 제어하려는 시도였습니다.
관련 문서:
3. 아무래도 제가 사용하는 텍스트필드가 UITextField를 사용하기 때문에 작동하지 않는게 아닐까 생각하였습니다.
검색 키워드를 바꿔 UITextField에서 글자 수를 제한하는 방법을 찾기 시작했고 마침내 해결 할 수 있었습니다.
이번 프로젝트에서는 TextField가 보일 시 자동으로 선택되는 FirstResponderTextField를 사용했었는데요.
기존 코드에 글자 수 제한 코드를 추가하였습니다.
struct FirstResponderTextField: UIViewRepresentable {
class Coordinator: NSObject, UITextFieldDelegate {
@Binding var searchText: String
var becameFirstResponder = false
init(searchText: Binding<String>) {
self._searchText = searchText
}
func textFieldDidChangeSelection(_ textField: UITextField) {
searchText = textField.text ?? ""
textField.text = String(searchText.prefix(15)) // 글자 수 제한
}
// 리턴키를 누를 시 포커스 해제
func textFieldShouldReturn(_ textField: UITextField) -> Bool {
textField.resignFirstResponder()
return true
}
}
@Binding var searchText: String
let placeHolder: String
func makeUIView(context: Context) -> some UIView {
let textField = UITextField()
textField.delegate = context.coordinator
textField.placeholder = placeHolder
return textField
}
func makeCoordinator() -> Coordinator {
return Coordinator(searchText: $searchText)
}
func updateUIView(_ uiView: UIViewType, context: Context) {
if !context.coordinator.becameFirstResponder {
uiView.becomeFirstResponder()
context.coordinator.becameFirstResponder = true
}
}
}
단 한줄을 추가하는 것으로 문제를 해결할 수 있었습니다.
func textFieldDidChangeSelection(_ textField: UITextField) {
searchText = textField.text ?? ""
textField.text = String(searchText.prefix(15)) // 글자 수 제한
}
ViewModel로부터 바인딩되는 SearchText에 textField.text의 값이 입력되는 구조입니다.
ViewModel에서 @Published var searchText: String = "" 의 String을 didSet 등등으로 제한하려고 했던 것은 실패하였는데요.
조금 더 내려와서(?) textField.text의 String을 제한하는 코드를 통해 문제가 해결되었습니다.
혹시 FirstResponderTextField를 사용하신다면 다음과 같이 사용 하실 수 있습니다.
FirstResponderTextField(searchText: $searchText, placeHolder: "검색")
'Project > SwiftUI 블록와이드' 카테고리의 다른 글
[SwiftUI Project] 앱에서 Email 보내기 OpenURL (0) | 2022.10.27 |
---|---|
[SwiftUI Project] 다크모드/라이트모드 전환 버튼 만들기 (0) | 2022.10.27 |
[SwiftUI Project] 뉴스기사 URL 공유 버튼 만들기 (0) | 2022.10.19 |
[SwiftUI Project] 네트워크 모니터 추가하기 (유튜브 스타일) (2) | 2022.10.19 |
[SwiftUI Project] 몇시간 전, 몇일 전 상대적 시간 구하기 RelativeDateTimeFormatter (0) | 2022.10.14 |
댓글