SwiftUI TextField force lowercase

Viewed 10464

I would like to use a specific TextField for url entries where the user could only enter lowercase characters, but I can't find any TextField modifier for this purpose. Is there any solution?

5 Answers

TextField has a .autocapitalization() method.

You can use like this without custom binding:

TextField("URL", text: $url)
                    .keyboardType(.URL)
                    .autocapitalization(.none)

For iOS 15 SwiftUI have a new .textInputAutocapitalization() method:

.textInputAutocapitalization(.never)

This means that any text input by the user will be .lowercased()

You can create a custom binding and set your state URL variable to the lowercased version of the input through it:

struct ContentView: View {
    @State var url: String = ""

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

        return VStack {
            TextField("Enter URL", text: binding)
        }

    }
}

XCODE 13

SwiftUI - IOS 15.0

FROM:
.autocapitalization(.none)

TO:
.textInputAutocapitalization(.never)

Example:

TextField("Enter URL", text: $url)
    .keyboardType(.URL)
    .textInputAutocapitalization(.never)

if all you want is to "end up" with a lowercase string after the user press return, you could do this:

@State var txt: String = ""

var body: some View {
        TextField("", text: $txt, onEditingChanged: { _ in
            self.txt = self.txt.lowercased()
        })
}

a more complicated but more flexible way, is something like this:

class LowerCaseStringFormatter: Formatter {

override func string(for obj: Any?) -> String? {
    guard let str = obj as? NSString else { return nil }
    return str.lowercased as String
}

override func getObjectValue(_ obj: AutoreleasingUnsafeMutablePointer<AnyObject?>?, for string: String, errorDescription error: AutoreleasingUnsafeMutablePointer<NSString?>?) -> Bool {
    obj?.pointee = string.lowercased() as NSString
    return true
}

override func isPartialStringValid(_ partialString: String, newEditingString newString: AutoreleasingUnsafeMutablePointer<NSString?>?, errorDescription error: AutoreleasingUnsafeMutablePointer<NSString?>?) -> Bool {
    return true
}

}

and call it like this:

 TextField("type something...", value: $txt, formatter: LowerCaseStringFormatter())
Related