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()
}
}