53

我似乎找不到任何信息或弄清楚如何在 SwiftUI 的 TextField 上设置键盘类型。能够启用安全文本属性、隐藏密码等也很好。

这篇文章展示了如何“包装”一个 UITextField,但如果我不需要,我宁愿不使用任何 UI 控件。 如何让 TextField 成为第一响应者?

任何人都知道如何在不包装老式 UI 控件的情况下做到这一点?

4

8 回答 8

89

要创建一个可以输入安全文本的字段,您可以使用SecureField($password)

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

如果您想将contentTypetextField 设置为例如。.oneTimeCode你可以这样做。也适用于keyboardType

TextField($code)
    .textContentType(.oneTimeCode)
    .keyboardType(.numberPad)
于 2019-06-10T14:55:24.907 回答
20

我们不再需要使用黑客。Beta 5 带来了一个新的修改器来设置键盘类型。例如,要使用数字键盘:

.keyboardType(.numberPad)

还有autocapitalization()一个 EnvironmentValue disableAutocorrection

于 2019-07-29T22:12:37.040 回答
8

要设置TextField's键盘类型,您需要添加修饰符.keyboardType()

TextField(placeHolder, text: "your text here")
    .keyboardType(.numberPad)
于 2019-12-11T06:45:01.063 回答
4

.keyboardType(.numberPad)在 TextField 上设置。简单的!

于 2019-12-11T05:11:24.783 回答
3

下面包装了一个UITextField名为UIKitTextFieldusing的类UIViewRepresentable。键盘类型设置为.decimalPad但可以设置为任何有效的键盘类型。

//  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)
  }
}

ContentView.Swift我创建了两个TextFields. 第一个是包装UIKit UITextField的,第二个是 SwiftUI TextField。数据绑定是相同的,因此每个都将显示与输入相同的文本。

// 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
于 2019-06-24T23:44:51.867 回答
1

Xcode 13 - iOS 和 WatchOS 应用程序

如果您正在制作 WatchOS 应用程序,同时作为 iOS 应用程序,您需要为操作系统检查添加条件,如下面的代码所示

           #if os(iOS)
            TextField(placeHolder, text: $text)
                .keyboardType(.numbersAndPunctuation)
            #endif
于 2021-12-24T21:51:58.357 回答
0

我是回答那个帖子的开发者——目前没有官方的方法可以这样做。目前最好的选择是包装 UITextField – Matteo Pacini

总结一下,猜想我们现在被困在包装 UITextField 上。

于 2019-06-09T19:25:18.017 回答
-1

这对我有用:

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
    }
}
于 2020-03-04T01:40:31.447 回答