代码之家  ›  专栏  ›  技术社区  ›  Maysam

更新状态变量不会更新TextField的文本

  •  0
  • Maysam  · 技术社区  · 4 年前

    我有 TextField 以应当在特定用户动作上动态更新的形式。既然我嵌入了这个 SwiftUI 内部视图 UIKit 视图,我不得不对其进行一些自定义:

    /// Base TextField
    struct CustomTextFieldSUI: View {
        @State var text: String = ""
        var placeholder: Text
        var disableAutoCorrect = false
        var isSecure: Bool = false
        var onEditingChanged: (Bool) -> () = { _ in }
        var onCommit: () -> () = { }
        var onChange: (String) -> Void
        var keyboardType: UIKeyboardType = .default
        var contentType: UITextContentType?
        
        var body: some View {
            
            ZStack(alignment: .leading) {
                if text.isEmpty {
                    placeholder
                        .foregroundColor(placeholderColor)
                }
                if isSecure {
                    SecureField("", text: $text.onChange({ newText in
                        onChange(newText)
                    }), onCommit: onCommit)
                        .foregroundColor(foregroundColor)
    
                       
                } else {
                    TextField("", text: $text.onChange({ newText in
                        onChange(newText)
                    }), onEditingChanged: onEditingChanged, onCommit: onCommit)
                        .foregroundColor(foregroundColor)
                        .disableAutocorrection(disableAutoCorrect)
                        .keyboardType(keyboardType)
                        .textContentType(contentType)
                        .autocapitalization(keyboardType == UIKeyboardType.emailAddress ? .none : .words)
                }
               
            }
        }
        
    }
    

    其本身用于创建另一个自定义视图:

    struct TextFieldWithIconSUI: View {
        @State var text: String = ""
        @State var isSecure: Bool
    
        let icon: Image
        let placeholder: String
        var prompt: String? = nil
        let disableAutoCorrect: Bool = false
        var keyboardType: UIKeyboardType = .default
        var contentType: UITextContentType?
        var onEditingChanged: (Bool) -> () = { _ in }
        var onCommit: () -> () = { }
        var onChange: (String) -> Void
    
        var body: some View {
            VStack {
                ZStack {
                    RoundedRectangle(cornerRadius: 0)
                                        HStack(alignment: .center, spacing: iconSpacing) {
                        CustomTextFieldSUI(
                            text: text,
                            placeholder: Text(placeholder),
                            placeholderColor: .gray,
                            foregroundColor: .white,
                            disableAutoCorrect: disableAutoCorrect,
                            isSecure: isSecure, onEditingChanged: onEditingChanged, onCommit: onCommit, onChange: { newText in
                                text = newText
                                onChange(newText)
                            },
                            keyboardType: keyboardType,
                            contentType: contentType)
                        
                        icon
                            .scaledToFit()
                            .onTapGesture {
                                isSecure.toggle()
                            }
                          
                            
                    }
                    
                }
                
                if (prompt != nil) {
                    VStack(alignment: .leading) {
                        Text(prompt!)
                            .padding(.leading, 10)
                            .padding(.top, -2)
                            .frame(maxWidth: .infinity, alignment: .leading)
                            .lineLimit(2)
                    }
                }
            }
        }
    }
    

    现在,在客户端视图中,我将它与列表一起使用,以创建一个简单的自动完成列表:

    TextFieldWithIconSUI(text: displayCountryName, isSecure: false, icon: emptyImage, placeholder: "Country", keyboardType: .default, contentType: .countryName, onEditingChanged: { changed in
        self.shouldShowCountriesList = changed
    }, onChange: { text in
        self.displayCountryName = text
        self.shouldShowCountriesList = true
    })
    

    在我表单的某个地方,我使用TextField中的文本来显示自动更正列表。会显示列表,但当我选择一个项时,它不会更新TextField的文本,在调试器中,状态变量会更新,但UI不会显示新值。

    if shouldShowCountriesList {
        VStack(alignment: .leading) {
            List {
                ForEach(countriesList.filter { $0.lowercased().hasPrefix(country.object.lowercased()) }.prefix(3), id: \.self) { countryName in
                    Text(countryName)
                            .onTapGesture {
                                self.displayCountryName = countryName
                                self.shouldShowCountriesList = false
                            }
                    
                }
            }
        }
    }
    
    0 回复  |  直到 4 年前
        1
  •  0
  •   Maysam    4 年前

    我不得不为我的自定义文本字段使用绑定变量:

    struct CustomTextFieldSUI: View {
        var text: Binding<String>
        var placeholder: Text
        var placeholderColor: Color
        var foregroundColor: Color
        var disableAutoCorrect = false
        var isSecure: Bool = false
        var onEditingChanged: (Bool) -> () = { _ in }
        var onCommit: () -> () = { }
        var onChange: (String) -> Void
        var keyboardType: UIKeyboardType = .default
        var contentType: UITextContentType?
        
        var body: some View {
            let bindingText = Binding(
                get: {
                    self.text.wrappedValue
                    
                },
                set: {
                    self.text.wrappedValue = $0
                onChange($0)
            })
            ZStack(alignment: .leading) {
                if text.wrappedValue.isEmpty {
                    placeholder
                        .foregroundColor(placeholderColor)
                }
    
                
                if isSecure {
                    SecureField("", text: bindingText, onCommit: onCommit)
                        .foregroundColor(foregroundColor)
    
                       
                } else {
                    TextField("", text: bindingText, onEditingChanged: onEditingChanged, onCommit: onCommit)
                        .foregroundColor(foregroundColor)
                        .disableAutocorrection(disableAutoCorrect)
                        .keyboardType(keyboardType)
                        .textContentType(contentType)
                        .autocapitalization(keyboardType == UIKeyboardType.emailAddress ? .none : .words)
                    
                }
               
            }
        }
        
    }
    
    

    并从主机传递绑定变量。