Home > database >  SwiftUI TextField prevent certain characters from being entered?
SwiftUI TextField prevent certain characters from being entered?

Time:08-27

How can I prevent certain characters from being entered into my SwiftUI TextField so that when a un-allowed character is entered it is completely ignored or replaced with "".

My code below only works by specifying a single character to ignore but I need to be able to specify many allowed characters without using a regex in my case (for readability).

I was trying to make it work based on existing SO articles but need assistance with how to check every new character as it is entered by comparing it to a range of allowed characters.

The TextField would also need to prevent spaces from being entered...

I have read a lot of SO articles on this NOT FOR SWIFTUI TEXTFIELDS AND they are not easily understood with regex expressions.

enum InputType {
    case username
    case code
}

struct AccountInput: View {
    let placeholder: String
    @Binding var input: String
    
    let inputType: InputType
 
    var body: some View {
        HStack {
            TextField(placeholder, text: $input)
                .onChange(of: input) { _ in
                    switch inputType {
                    case .username:
                        let allowedCharacters = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789._-"
                        let allowedCharacterSet = CharacterSet(charactersIn: allowedCharacters)
                        let typedCharacterSet = CharacterSet(charactersIn: input)
                        input = input.replacingOccurrences(of: ???, with: "")
                        // ^ HOW CAN I MODIFY THIS TO CHECK AND SEE IF CHARACTER IS CONTAINED IN ALLOWED CHARACTER SET AND IGNORE SPACES???
                    case .code:
                        let allowedCharacters = "0123456789"
                        let allowedCharacterSet = CharacterSet(charactersIn: allowedCharacters)
                        let typedCharacterSet = CharacterSet(charactersIn: input)
                        input = input.replacingOccurrences(of: " ", with: "")
                    }
                }
        }
    }

    init(placeholder: String, input: Binding<String>, inputType: InputType) {
        self.placeholder = placeholder
        self._input = Binding(projectedValue: input)
        self.inputType = inputType
    }
    
}

CodePudding user response:

Here is one approach, using Combine:

import SwiftUI
import Combine

struct TextFiltering: View {

    @State private var userName = ""
    @State private var codeNumber = ""

    var body: some View {
        HStack {
            TextField("Username", text: $userName)
                .background(Color.cyan)
                .onReceive(Just(userName)) { newValue in
                    let allowedCharacters = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789._-"
                    let filtered = newValue.filter { allowedCharacters.contains($0) }
                    if filtered != newValue {
                        self.userName = filtered
                    }
                }
            Spacer()
            TextField("Code", text: $codeNumber)
                .background(Color.yellow)
                .onReceive(Just(codeNumber)) { newValue in
                    let allowedCharacters = "0123456789"
                    let filtered = newValue.filter { allowedCharacters.contains($0) }
                    if filtered != newValue {
                        self.codeNumber = filtered
                    }
                }
        }
    }

}

struct TextFiltering_Previews: PreviewProvider {
    static var previews: some View {
        TextFiltering()
    }
}
  • Related