I can\'t seem to find any information or figure out how to set the keyboard type on a TextField for SwiftUI. It would also be nice to be able to enable the secure text property,
The following wraps a UITextField class called UIKitTextField using UIViewRepresentable. The keyboard type is set to .decimalPad but could be set to any valid keyboard type.
// UIKitTextField.swift
import UIKit
class UIKitTextField: UITextField, UITextFieldDelegate {
required init(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)!
delegate = self
}
required override init(frame: CGRect) {
super.init(frame: frame)
delegate = self
self.setContentHuggingPriority(.defaultHigh, for: .vertical)
}
}
In the ContentView.Swift I created two TextFields. The first is the wrapped UIKit UITextField and the second is the SwiftUI TextField. The data binding is the same so each will display the same text as it is entered.
// ContentView.Swift
import SwiftUI
import UIKit
struct MyTextField : UIViewRepresentable {
@Binding var myText: String
func makeCoordinator() -> MyTextField.Coordinator {
return Coordinator(text: $myText)
}
class Coordinator: NSObject {
@Binding var text: String
init(text: Binding<String>) {
$text = text
}
@objc func textFieldEditingChanged(_ sender: UIKitTextField) {
self.text = sender.text ?? ""
}
}
func makeUIView(context: Context) -> UIKitTextField {
let myTextField = UIKitTextField(frame: .zero)
myTextField.addTarget(context.coordinator, action: #selector(Coordinator.textFieldEditingChanged(_:)), for: .editingChanged)
myTextField.text = self.myText
myTextField.placeholder = "placeholder"
myTextField.borderStyle = .roundedRect
myTextField.keyboardType = .decimalPad
return myTextField
}
func updateUIView(_ uiView: UIKitTextField,
context: Context) {
uiView.text = self.myText
}
}
struct MyTextFieldView: View {
@State var myText: String = "Test"
var body: some View {
VStack {
MyTextField(myText: $myText)
.padding()
TextField($myText)
.textFieldStyle(.roundedBorder)
.padding()
}
}
}
#if DEBUG
struct ContentView_Previews : PreviewProvider {
static var previews: some View {
Group{
MyTextFieldView().previewLayout(.sizeThatFits)
MyTextFieldView().previewDevice("iPhone Xs")
}
}
}
#endif
Set .keyboardType(.numberPad) on the TextField. Simple!
To set TextField's keyboard type you need to add modifier .keyboardType().
TextField(placeHolder, text: your text)
.keyboardType(.numberPad)
We no longer need to use hacks. Beta 5 has brought a new modifier to set the keyboard type. For example, to use a number pad:
.keyboardType(.numberPad)
There's also autocapitalization() and an EnvironmentValue disableAutocorrection.
This works for me:
import UIKit
import SwiftUI
class UIKitTextField: UITextField, UITextFieldDelegate {
required init(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)!
delegate = self
}
required override init(frame: CGRect) {
super.init(frame: frame)
delegate = self
self.setContentHuggingPriority(.defaultHigh, for: .vertical)
}
func textFieldShouldReturn(_ textField: UITextField) -> Bool {
resignFirstResponder()
return true
}
}
struct UBSTextField : UIViewRepresentable {
@Binding var myText: String
let placeHolderText: String
func makeCoordinator() -> UBSTextField.Coordinator {
return Coordinator(text: $myText)
}
class Coordinator: NSObject {
var textBinding: Binding<String>
init(text: Binding<String>) {
self.textBinding = text
}
@objc func textFieldEditingChanged(_ sender: UIKitTextField) {
self.textBinding.wrappedValue = sender.text ?? ""
}
}
func makeUIView(context: Context) -> UIKitTextField {
let textField = UIKitTextField(frame: .zero)
textField.addTarget(context.coordinator, action: #selector(Coordinator.textFieldEditingChanged(_:)), for: .editingChanged)
textField.text = self.myText
textField.placeholder = self.placeHolderText
textField.borderStyle = .none
textField.keyboardType = .asciiCapable
textField.returnKeyType = .done
textField.autocapitalizationType = .words
textField.clearButtonMode = .whileEditing
return textField
}
func updateUIView(_ uiView: UIKitTextField,
context: Context) {
uiView.text = self.myText
}
}
I'm the dev that answered that post - there's no official way to do so at the moment. Your best bet at the moment is to wrap UITextField – Matteo Pacini
That sums it up, guess we are stuck with wrapping UITextField for now.