SwiftUI TextField Simple Example not working

Viewed 7875

I tried to create a very simple TextField in SwiftUI but I cannot get it to work and I don't understand what I am doing wrong.

Xcode gives me an error message that says:

"Unable to infer complex closure return type; add explicit type to disambiguate."

I am not sure what to do. I found some other code examples for TextFields with SwiftUI on StackOverflow but keep getting the same error.

struct TextFieldExample : View {
    @State var email: String = "Enter email address"
    var body: some View {
        VStack {
            TextField($email)
            Text("Your email is \(email)!")
        }
    }
}
struct ButtonTextField : View {
    @State var text: String = ""

    var body: some View {
        HStack {
            TextField($text,
                      placeholder: Text("type something here..."))
            Button(action: {
                // Closure will be called once user taps your button
                print(self.$text)
            }) {
                Text("SEND")
            }
        }
    }
}

Expected results = working TextField Actual result = Error in Xcode

4 Answers

It seems the TextField view has been changed in a recent beta release. You should be able to create one using something like this:

struct MyView {
    @State var myInput: String = ""
    var body: some View {
      TextField("placeholder text", text: $myInput)
    }
}

In the recent beta release of Xcode TextField has been changed.

@State var email: String = ""

    var body: some View {
       TextField("Email", text: $email, onEditingChanged: { (isChanges) in
           // On Editing Changed
       }) {
           // On Commit
       }
       .padding(.leading, 13).padding(.trailing, 13).padding(.top, UIScreen.main.bounds.size.height / 2)
       .textContentType(.emailAddress)
       .textFieldStyle(RoundedBorderTextFieldStyle.init())
    }

First of all do you really need to combine these Views into a custom view? If yes than:

  1. @State and BindableObject should be passed into the view to the property marked with @Binding keyword
  2. Don't use the same name as some of the native classes have

    struct MyTextField : View {
    
    @Binding var email: String
    
    var body: some View {
        VStack {
            Text("Your email is \(email)!")
            TextField($email, placeholder: Text("Enter your email"))
        }
      }
    }
    

Call it like this

@State private var email: String = ""

var body: some View {
    MyTextField(email: $email)
}

TextField like SearchView - XCODE 11.3

struct SearchBarV: View {

     @State var text: String = ""
     var onEditingChanged: (Bool) -> Void = { _ in }
     var onCommit: () -> Void = { }

     var body: some View {

         GeometryReader { metrics in
             TextField("placeholder", text: self.$text, onEditingChanged: self.onEditingChanged, onCommit: self.onCommit)
            .background(Color.gray.opacity(0.1))
            .padding(EdgeInsets(top: 0.0, leading: 16.0, bottom: 0, trailing: 16.0))
            .frame(width: metrics.size.width, height: 50)
            .keyboardType(.emailAddress)
        }

    }
}


 struct SearchBarV_Previews : PreviewProvider {
     static var previews: some View {
        SearchBarV()
     }
 }
Related