Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Filtering entered/pasted characters #43

Open
ZsoltMolnarMBH opened this issue Mar 16, 2022 · 0 comments
Open

Filtering entered/pasted characters #43

ZsoltMolnarMBH opened this issue Mar 16, 2022 · 0 comments

Comments

@ZsoltMolnarMBH
Copy link

ZsoltMolnarMBH commented Mar 16, 2022

Users can input any characters either by using a physical keyboard, or copy pasting into FormatTextField.

The issue is most prominent when the user is trying to paste something. Here is our example:

private struct AccountEditorView: View {
    @Binding var text: String
    let prompt: String
    let textColor: Color
    let cursorColor: Color

    var body: some View {
        FormatTextField(
            unformattedText: $text,
            placeholder: prompt,
            textPattern: "######## - ######## - ########"
        )
            .font(.body1)
            .keyboardType(.numberPad)
            .foregroundColor(textColor)
            .accentColor(cursorColor)
    }
}

user pastes: 12345678 - 12345678 - 12345678
FormatTextField shows: 12345678 - 12345678 - 12

Despite Tinamu's suggestion on a previous issue, this problem cannot be solved on SwiftUI view level, nor with using .onReceive modifier, nor with using a custom Binding implementation that filters the input, because these filtering closures run after the paste happened.

Suggested solution

FormatTextField should accept an optional CharacterSet as an init argument.
If given, use this characterset to filter user input at the very first line of
public func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool

The following proof of concept solution seems to fix the problem:

        private let  allowedInput: CharacterSet = .decimalDigits
        
        public func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {
            let string = String(string.unicodeScalars.filter { self.allowedInput.contains($0) })
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants