Keyboard type in SwiftUI

Haven't seen anyone set, show or say how to set the Keyboard type for a TextField in SwiftUI yet. For example numberic or email keyboards etc.


Can't seem to figure it out. Anyone else have any ideas?


EDIT: For now there doesn't seem to be a way other than interfacing with UIKit. Doing so, one could interface with a UITextView and set the keyboard type there. Hopefully in the near future Apple will make simple things like choosing keyboard type and having password fields available in SwiftUI, but for now it seems we are stuck with interfacing.

Replies

We're on the same boat... It seems it is not possible to select the keyboard. I also could not locate a way of making a TextField the firstResponder, so that it gets focus.


As for the password fields, you can use SecureField, instead of TextField:


https://developer.apple.com/documentation/swiftui/securefield

At first I created a UIViewRepresentable to wrap a UITextField... and that works... There is, however, another option which takes advantage of the fact that it seems the SwiftUI TextField is actually already implemented as a UITextField. By observing the UITextField.textDidBeginEditingNotification I managed to change the keyboard.


This is an ugly, ugly hack... that works. I leave it hear mostly for purely academic purposes... I don't think I would like to use this on production code:


import SwiftUI

let dirtyWork = DirtyWork()

struct ContentView : View {
    @State private var emailAccount: String = ""
    @State private var twitterAccount: String = ""
    
    var body: some View {
        return VStack {
            
            TextField($emailAccount, onEditingChanged: { if $0 { dirtyWork.keyboardType = .emailAddress } }).textFieldStyle(.roundedBorder)
            
            TextField($twitterAccount, onEditingChanged: {  if $0 { dirtyWork.keyboardType = .twitter } }).textFieldStyle(.roundedBorder)
            
            Spacer()
        }
        
    }
}

class DirtyWork {
    var keyboardType: UIKeyboardType = .twitter // some default
    
    init() {
        NotificationCenter.default.addObserver(self, selector: #selector(didBegin(notification:)), name: UITextField.textDidBeginEditingNotification, object: nil)
    }
    
    @objc func didBegin(notification: Notification) {
        
        if let tf = notification.object as? UITextField {
            tf.keyboardType = keyboardType
        }
        
    }
}

Not sure if this helps (pretty sure it doesn't change the keyboard from my testing), but .textContentType(.[TYPE OF CONTENT]) appears to have the same selections and UIKit did and changes the autocorrection's pickiness. However, in my testing using the phone number option, I was unable to actually get the numpad to open up. Example below:

Group {
  TextField($username, placeholder: Text("Username"))
     .textContentType(.username)
  SecureField($password, placeholder:  Text("Password"))
     .textContentType(.password)
}


EDIT:


Below is a link to Apple's documentation regarding textContentType()'s implementation in UIKit, saying "When you provide this information about the content you expect users to enter in a text input area, the system can in some cases automatically select an appropriate keyboard and improve keyboard corrections and proactive integration with other text input opportunities."

https://developer.apple.com/documentation/uikit/uitextinputtraits/1649656-textcontenttype?language=objc

Yeap, I saw the textContentType and I was very excited, but then I tested it and nothing happened. 😕


Also note that UITextField uses UIKeyboardType to determine the keyboard to use, not UIContextType. For example, you can select UIKeyboardType.twitter, but there's no UIContextType.twitter. So it is not the same thing.


Please create a bug report, I already did (FB6169169). The more the merrier, and make sure to refer to FB6169169.

Beta 5 has a new modifier to set keyboard type:


TextField("Enter text", text: $val).keyboardType(.numberPad)