2

My iOS SwiftUI TextField allows the user to input an Int. If the user types bad input characters such as "abc" instead of "123", I would like to display the bad characters in an error message in my Text (where I wrote textField.text), and I would like to keep the TextField's keyboard on the screen until the user provides correct input. How to make this happen? Thank you in advance. Xcode 11.6 on macOS Catalina 10.15.6.

struct ContentView: View {
    @State private var value: Int? = nil;
    @State private var text: String = "";

    var body: some View {
        VStack {
            TextField(
                "Enter an integer:",
                value: $value,
                formatter: NumberFormatter(),
                onCommit: {
                    guard let value: Int = self.value else {
                        self.text = "Bad input \"\(textField.text)\".";
                        //Do not dismiss the TextField's keyboard.
                        return;
                    }
                    //Dismiss the TextField's keyboard.
                    self.text = "The product is \(2 * value).";
                }
            )
            .keyboardType(.numbersAndPunctuation)
            .textFieldStyle(RoundedBorderTextFieldStyle())

            Text(text)
        }
        .padding([.leading, .trailing], 16)
    }
}

1
  • TextField for now not possible to accomplish such functionality. You need to use representable over UITextField. Commented Aug 17, 2020 at 13:00

2 Answers 2

3

Below code gives you an idea for validating your text inside the textfield while user is typing.

struct ContentView: View {

@State private var textNumber    : String = ""
@State private var isNumberValid : Bool   = true

var body: some View {
    VStack {
        
        TextField("Enter an integer:", text: numberValidator())
            .keyboardType(.numbersAndPunctuation)
            .textFieldStyle(RoundedBorderTextFieldStyle())
        
        if !self.isNumberValid {
            Text("Bad input \"\(textNumber)\".")
                .font(.callout)
                .foregroundColor(Color.red)
        }
    }
    .padding([.leading, .trailing], 16)
}

private func numberValidator() -> Binding<String> {
    return Binding<String>(
        get: {
            return self.textNumber
    }) {
        if CharacterSet(charactersIn: "1234567890").isSuperset(of: CharacterSet(charactersIn: $0)) {
            self.textNumber = $0
            self.isNumberValid = true
        } else {
            self.textNumber = $0
            //self.textNumber = ""
            self.isNumberValid = false
        }
    }
  }
}
Sign up to request clarification or add additional context in comments.

Comments

0

The following code snippet gives you an idea to validate your text inside the text field as the user is typing using Get, Set value

    let checkValue = Binding<String>(
        get: {
            self.value
        },
        set: {
            self.value = $0
        }
    )

I hope it can be of help to you

struct ContentView: View {
    @State private var value: String = ""
    @State private var text: String = ""

    var body: some View {
        let checkValue = Binding<String>(
            get: {
               self.value
            },
            set: {
                self.value = $0
            }
        )

        return VStack {
            TextField("Enter an integer:",text: checkValue)
            .keyboardType(.numbersAndPunctuation)
            .textFieldStyle(RoundedBorderTextFieldStyle())

            Text("Bad interger: \(Int(self.value) != nil ? "" : self.value)").foregroundColor(Color.red)
        
        }
        .padding([.leading, .trailing], 16)
    }
}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.