Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

SwiftUI validate input in textfields

Tags:

swift

swiftui

I am trying to validate user input in a TextField by removing certain characters using a regular expression. Unfortunately, I am running into problems with the didSet method of the text var calling itself recursively.

import SwiftUI
import Combine

class TextValidator: ObservableObject {

    @Published var text = "" {
        didSet {
            print("didSet")
            text = text.replacingOccurrences(
                of: "\\W", with: "", options: .regularExpression
            ) // `\W` is an escape sequence that matches non-word characters.
        }
    }

}


struct ContentView: View {

    @ObservedObject var textValidator = TextValidator()

    var body: some View {
        TextField("Type Here", text: $textValidator.text)
            .padding(.horizontal, 20.0)
            .textFieldStyle(RoundedBorderTextFieldStyle())

    }
}

On the swift docs (see the AudioChannel struct), Apple provides an example in which a property is re-assigned within its own didSet method and explicitly notes that this does not cause the didSet method to be called again. I did some testing in a playground and confirmed this behavior. However, things seem to work differently when I use an ObservableObject and a Published variable.

How do I prevent the didSet method from calling itself recursively?

I tried the examples in this post, but none of them worked. Apple may have changed things since then, so this post is NOT a duplicate of that one.

Also, setting the text back to oldValue within the didSet method upon encountering invalid characters would mean that if a user pastes text, then the entire text would be removed, as opposed to only the invalid characters being removed. So that option won't work.

like image 329
Peter Schorn Avatar asked Apr 07 '20 05:04

Peter Schorn


People also ask

How do you validate text in Swift?

The validation takes a string from the parameter word, which then checks if in TextField contains that word. If TextField is not empty and the word can be found in TextField , then the function will return true. Otherwise, it will return false.

How check TextField is empty or not in Swift?

Basic Swift Code for iOS Apps Follow the below steps. Step 2 − Open Main. storyboard add one textField, one button and one label one below other as shown in the figure. On click of the button we will check whether the text field is empty or not and show the result in label.

How do I get TextField value in SwiftUI?

struct ContentView: View { @State private var name: String = "Tim" var body: some View { VStack(alignment: . leading) { TextField("Enter your name", text: $name) Text("Hello, \(name)!") } } } When that's run, you should be able to type into the text field and see a greeting appear directly below.


1 Answers

Try to validate what you want in the TextField onRecive method like this:

class TextValidator: ObservableObject {

    @Published var text = ""

}

struct ContentView: View {

    @ObservedObject var textValidator = TextValidator()
    var body: some View {
        TextField("Type Here", text: $textValidator.text)
            .padding(.horizontal, 20.0)
            .textFieldStyle(RoundedBorderTextFieldStyle())
            .onReceive(Just(textValidator.text)) { newValue in
                let value = newValue.replacingOccurrences(
                    of: "\\W", with: "", options: .regularExpression)
                if value != newValue {
                    self.textValidator.text = value
                }
                print(newValue)
        }
    }
}
like image 90
Mac3n Avatar answered Oct 14 '22 03:10

Mac3n