상세 컨텐츠

본문 제목

[SwiftUI] CustomTextField + ToolBar 사용방법과 문제점

IOS/문제해결

by 카키IOS 2024. 8. 28. 14:25

본문

SwiftUI에서 TextField와 ToolBarItem

struct ContentsView: View {
    @Binding var text: String
    var body: some View {
        VStack {
            TextField("", text: $text)
                .toolbar {
                    ToolbarItemGroup(placement: .keyboard) {
                        Spacer()
                        Button("Done") {
                            print("Done 눌림")
                        }
                    }
                }
        }
    }
}

커스텀 텍스트 필드의 사용

  • 코드 확장성을 고려한 TextField를 만들어 보겠습니다
  • ToolBar 사용법을 고려한 글 이기 때문에 별도의 기능이 없는 커스텀 텍스트필드 입니다
struct CustomTextField: View {
    let titleText: String
    @Binding var text: String

    var body: some View {
        VStack(spacing: 8) {
            Text(titleText)
                .frame(maxWidth: .infinity, alignment: .leading)

            TextField("", text: $text)
                .toolbar {
                    ToolbarItemGroup(placement: .keyboard) {
                        Spacer()
                        Button("Done") {
                            print("Done 눌림")
                        }
                    }
                }
        }
    }
}

만든 커스텀 텍스트필드의 사용

struct ContentView: View {
    @State var idText: String = ""
    @State var pwText: String = ""

    var body: some View {
        VStack {
            CustomTextField(titleText: "아이디", text: $idText)
            CustomTextField(titleText: "비밀번호", text: $pwText)
        }
        .padding(.horizontal, 16)
    }

}

문제점

  • ToolBar의 Done 버튼이 두개가 보여지는 현상
  • CustomTextField가 3개 혹은 n개를 하나의 뷰에서 사용할경우 Done버튼 역시 3개…n개가 보여지는 현상이 발생

문제 해결

struct CustomTextField: View {
    let titleText: String
    @Binding var text: String

    @FocusState private var isFocused: Bool //포커스

    var body: some View {
        VStack(spacing: 8) {
            Text(titleText)
                .frame(maxWidth: .infinity, alignment: .leading)

            TextField("", text: $text)
                .focused($isFocused) // 포커스
                .toolbar {
                    ToolbarItemGroup(placement: .keyboard) {
                        // 포커스 상태가 true인 경우에만 Done 버튼 표시
                        if isFocused {
                            Spacer()
                            Button("Done") {
                                print("Done 눌림")
                            }
                        }
                    }
                }
        }
    }
}
  • @FocusState로 텍스트필드에 포커스가 있을 경우에만 Done 버튼이 등장하도록 수정

728x90
반응형

관련글 더보기