반응형
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)
)
}
}
반응형