Ios 如何创建一个自定义文本输入,该输入具有在SwiftUI中同时充当安全字段(带眼睛图标)和普通文本字段的功能
我是SwiftUI的新手。我想开发一个定制的TextField,它接受一个参数,将自身更改为具有显示和隐藏密码功能的安全字段。但我现在遇到了一个问题。由于自定义textfield的调用方将状态变量作为参数传递,因此我必须在类中使用@Binding。但是当我使用绑定时,文本会在单击眼睛图标时消失。如果我上面描述的或下面编码的假设有任何错误,请纠正我Ios 如何创建一个自定义文本输入,该输入具有在SwiftUI中同时充当安全字段(带眼睛图标)和普通文本字段的功能,ios,swift,swiftui,Ios,Swift,Swiftui,我是SwiftUI的新手。我想开发一个定制的TextField,它接受一个参数,将自身更改为具有显示和隐藏密码功能的安全字段。但我现在遇到了一个问题。由于自定义textfield的调用方将状态变量作为参数传递,因此我必须在类中使用@Binding。但是当我使用绑定时,文本会在单击眼睛图标时消失。如果我上面描述的或下面编码的假设有任何错误,请纠正我 import SwiftUI struct BTextInput: View { @Binding var valueHolder : St
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)
}
}
}
如果我们将“@Binding var valueHolder:String”更改为“@State var valueHolder:String”,则此代码将按预期工作。但我需要将其本身作为绑定变量保存,因为这是一个自定义TextInput
如果你能提出更好的方法来达到同样的效果,那将是值得赞赏的。
(还有我代码中的错误/更好的编码实践)
提前感谢如果不考虑可视性变化中的焦点丢失,一切正常。我假设您对在预览中使用常量绑定感到困惑,因为绑定实际上是被动的——它是负责更新的状态。因此,要预览依赖于绑定的组件,需要具有活动状态的辅助视图,如下所示:
struct BTextInput_Previews: PreviewProvider {
struct TestSecureFieldSwitch: View {
@State private var text = ""
@State private var pass = ""
var body: some View {
VStack{
BTextInput(valueHolder: $text, hint: "Account")
BTextInput(valueHolder: $pass, hint: "Password", isSecure: true)
}
}
}
static var previews: some View {
TestSecureFieldSwitch()
}
}
使用Xcode 11.4/iOS 13.4进行测试,如果不考虑可见性变化中的焦点丢失,则一切正常。我假设您对在预览中使用常量绑定感到困惑,因为绑定实际上是被动的——它是负责更新的状态。因此,要预览依赖于绑定的组件,需要具有活动状态的辅助视图,如下所示:
struct BTextInput_Previews: PreviewProvider {
struct TestSecureFieldSwitch: View {
@State private var text = ""
@State private var pass = ""
var body: some View {
VStack{
BTextInput(valueHolder: $text, hint: "Account")
BTextInput(valueHolder: $pass, hint: "Password", isSecure: true)
}
}
}
static var previews: some View {
TestSecureFieldSwitch()
}
}
使用Xcode 11.4/iOS 13.4进行测试我可以再问你一个疑问吗?在SecureField中,如果我们键入任何内容并从组件中调出焦点,然后再次尝试在SecureField中键入内容,它会清除以前键入的值吗?这是SecureField的默认行为吗?@prebeesh,不确定我是否理解正确,但SecureField只是通过绑定显示字符串,它本身不会重置/清除任何内容。如果绑定字符串变量(State或Published)中有字符,那么它们将显示在Text/Secure字段中。好的,非常感谢。我还无法在stackoverflow中投票支持你的答案,否则我肯定会投票支持你的帮助。我能再问你一个疑问吗?在SecureField中,如果我们键入任何内容并从组件中调出焦点,然后再次尝试在SecureField中键入内容,它会清除以前键入的值吗?这是SecureField的默认行为吗?@prebeesh,不确定我是否理解正确,但SecureField只是通过绑定显示字符串,它本身不会重置/清除任何内容。如果绑定字符串变量(State或Published)中有字符,那么它们将显示在Text/Secure字段中。好的,非常感谢。在stackoverflow中,我还不能对答案投赞成票,否则我肯定会对你的帮助投赞成票。