I am new to SwiftUI. I wanted to develop a custom TextField which accepts a parameter for changing itself as a secure field with show and hide password facility. But I am stuck with an issue now. As the caller of my custom textfield will pass a State variable as parameter, i have to use @Binding here inside my class. But when i use binding, the text gets disappear while clicking the eye icon. Kindly correct me if my assumptions described above or coded below has any mistakes.
import SwiftUI
struct BTextInput: View {
@Binding var valueHolder : String
var hint : String?
@State var isSecure: Bool?
@State var isTextHidden: Bool = true
var body: some View {
HStack{
if isSecure ?? false{
if isTextHidden {
VStack{
SecureField("\(hint.optionalVal)" ,text : self.$valueHolder)
.lineLimit(1)
.multilineTextAlignment(.leading)
.padding(.horizontal,4)
.padding(.trailing,28)
Rectangle().frame(height: 0.5)
.foregroundColor(.gray)
}.overlay(
Button(action: {
self.isTextHidden.toggle()
}){
EyeImage(name: "eye")
}.padding(.top,2.5)
,alignment: .topTrailing)
}else{
VStack{
TextField("\(hint.optionalVal)" ,text : self.$valueHolder)
.lineLimit(1)
.multilineTextAlignment(.leading)
.padding(.horizontal,4)
.padding(.trailing,28)
Rectangle().frame(height: 0.5)
.foregroundColor(.gray)
}.overlay(
Button(action: {
self.isTextHidden.toggle()
}){
EyeImage(name: "eye.slash")
}.padding(.top,2.5)
,alignment: .topTrailing)
}
}else{
VStack{
TextField("\(hint.optionalVal)" ,text : self.$valueHolder)
.lineLimit(1)
.multilineTextAlignment(.leading)
.padding(.horizontal,4)
Rectangle().frame(height: 0.5)
.foregroundColor(.gray)
}
}
}.padding()
}
}
struct EyeImage: View {
private var imageName: String
init(name: String) {
self.imageName = name
}
var body: some View {
Image(systemName : imageName)
.foregroundColor(.black)
}
}
struct BTextInput_Previews: PreviewProvider {
static var previews: some View {
VStack{
BTextInput(valueHolder: Binding.constant(""), hint: "Account")
BTextInput(valueHolder: Binding.constant(""), hint: "Account", isSecure: true)
}
}
}
This code will work as expected if we change the '@Binding var valueHolder : String' as '@State var valueHolder : String'. But I need to keep it as a binding variable itself as this is a custom TextInput.
It will be appreciable if you can suggest any better approach to achieve the same. (Also the mistakes in my code / better coding practises) Thanks in advance