Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/ios/113.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/swift/17.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ios 如何创建一个自定义文本输入,该输入具有在SwiftUI中同时充当安全字段(带眼睛图标)和普通文本字段的功能_Ios_Swift_Swiftui - Fatal编程技术网

Ios 如何创建一个自定义文本输入,该输入具有在SwiftUI中同时充当安全字段(带眼睛图标)和普通文本字段的功能

Ios 如何创建一个自定义文本输入,该输入具有在SwiftUI中同时充当安全字段(带眼睛图标)和普通文本字段的功能,ios,swift,swiftui,Ios,Swift,Swiftui,我是SwiftUI的新手。我想开发一个定制的TextField,它接受一个参数,将自身更改为具有显示和隐藏密码功能的安全字段。但我现在遇到了一个问题。由于自定义textfield的调用方将状态变量作为参数传递,因此我必须在类中使用@Binding。但是当我使用绑定时,文本会在单击眼睛图标时消失。如果我上面描述的或下面编码的假设有任何错误,请纠正我 import SwiftUI struct BTextInput: View { @Binding var valueHolder : St

我是SwiftUI的新手。我想开发一个定制的TextField,它接受一个参数,将自身更改为具有显示和隐藏密码功能的安全字段。但我现在遇到了一个问题。由于自定义textfield的调用方将状态变量作为参数传递,因此我必须在类中使用@Binding。但是当我使用绑定时,文本会在单击眼睛图标时消失。如果我上面描述的或下面编码的假设有任何错误,请纠正我

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中,我还不能对答案投赞成票,否则我肯定会对你的帮助投赞成票。