How to set Keyboard type of TextField in SwiftUI?

混江龙づ霸主 提交于 2019-12-05 00:51:15

To create a field where you can enter secure text you can use SecureField($password)

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

If you want to set the contentType of an textField to eg. .oneTimeCode you can do it like this. Also works with keyboardType

TextField($code)
    .textContentType(.oneTimeCode)
    .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.

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

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.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!