카테고리 없음 / / 2023. 7. 24. 16:04

SwiftUI TextField에서 isSecureTextEntry 적용하여 비밀번호 입력창 만들기

반응형

SwiftUI에서 수정중인 상태에서는 테두리를 변경하고

입력한 글자를 *로 가리고 on off 버튼을 통해 입력한 글자를 보여주는 TextField 생성

 

SwiftUI에서는 @FocusStat와 SecureField를 이용하면

쉽게 비밀번호 입력창을 만들 수 있지만 @FocusStat는 iOS 15 이상부터 사용이 가능하다.

또한 SecureField에서는 onEditingChanged 값을 받을 수 없기때문에 입력중인 상태를 구분하기 어렵다.

 

그래서 UIViewRepresentable를 이용해 UIkit의 UITextField()를 사용하여 비밀번호 입력창을 생성

 

 

SecureTextField 생성

struct SecureTextField: UIViewRepresentable {
    @Binding var text: String
    @Binding var isEditing: Bool
    @Binding var isSecure: Bool

    func makeUIView(context: Context) -> UITextField {
        let textField = UITextField()
        // 초기에 비밀번호 보이기/숨기기 상태를 설정
        textField.isSecureTextEntry = isSecure
        textField.delegate = context.coordinator
        return textField
    }

    func updateUIView(_ uiView: UITextField, context: Context) {
        // 텍스트 및 보안 설정 업데이트
        uiView.text = text
        uiView.isSecureTextEntry = isSecure

        if isEditing {
            // 편집 중일 때 키보드를 올리도록
            uiView.becomeFirstResponder()
        } else {
            // 편집 상태가 아닐 때 키보드를 내리도록
            uiView.resignFirstResponder()
        }
    }

    func makeCoordinator() -> Coordinator {
        Coordinator(text: $text, isEditing: $isEditing, isSecure: $isSecure)
    }

    class Coordinator: NSObject, UITextFieldDelegate {
        @Binding var text: String
        @Binding var isEditing: Bool
        @Binding var isSecure: Bool

        init(text: Binding<String>, isEditing: Binding<Bool>, isSecure: Binding<Bool>) {
            _text = text
            _isEditing = isEditing
            _isSecure = isSecure
        }

        func textFieldDidBeginEditing(_ textField: UITextField) {
            // 텍스트 필드 편집이 시작될 때, isEditing 상태를 true로 설정하여 노란색 테두리를 보여줌
            isEditing = true
        }

        func textFieldDidEndEditing(_ textField: UITextField) {
            // 텍스트 필드 편집이 끝날 때, isEditing 상태를 false로 설정하여 파란색 테두리를 보여주고, 현재 텍스트 값을 업데이트
            isEditing = false
            text = textField.text ?? ""
        }
    }
}

 

SecureTextField와 on off 버튼 생성

struct ContentView: View {
    @State private var password: String = ""
    @State private var isEditing: Bool = false
    @State private var isSecure: Bool = true

    var body: some View {
        HStack {
            SecureTextField(text: $password, isEditing: $isEditing, isSecure: $isSecure)
                .padding()
                .textFieldStyle(.plain)
                .frame(height: 50)

            Button(action: {
                if isEditing {
                    // 편집 중이라면 키보드를 내리기 위해 리스폰더 해제
                    UIApplication.shared.sendAction(#selector(UIResponder.resignFirstResponder), to: nil, from: nil, for: nil)
                } else {
                    // 편집 중이 아니라면 키보드를 올리기 위해 리스폰더 등록
                    UIApplication.shared.sendAction(#selector(UIResponder.becomeFirstResponder), to: nil, from: nil, for: nil)
                }

                // 비밀번호 보이기/숨기기 토글
                isSecure.toggle()
                // 편집 상태 해제
                isEditing = false
            }, label: {
                Image(systemName: isSecure ? "eye" : "eye.slash")
            })
            .padding(.trailing, 5)
        }
        .overlay(
            // 편집 중일 때 노란색 테두리를, 그렇지 않을 때 파란색 테두리를 적용
            RoundedRectangle(cornerRadius: 8)
                .stroke(isEditing ? Color.yellow : Color.blue, lineWidth: 2)
        )
    }
}
반응형
  • 네이버 블로그 공유
  • 네이버 밴드 공유
  • 페이스북 공유
  • 카카오스토리 공유