在点击期间格式化TextField文本

时间:2019-11-13 14:32:45

标签: ios swift swiftui

我正在尝试在TextField中的swiftui中设置文本格式,以添加诸如此类的空间:

文字更改时: 191064221849132 拥有1 91 06 42 218 491 32

我尝试了一些@state和@Binding,但实际上没有任何作用。

1 个答案:

答案 0 :(得分:1)

您应该使用自定义FormatteronCommit处理程序。令人讨厌的是,这些内容不会在您键入时应用,而仅在您提交编辑时才应用

Formatter示例:

final class CapitalizedFormatter: Formatter {
  override func string(for obj: Any?) -> String? {
    guard let string = obj as? String else {
      return ""
    }
    return string.uppercased()
  }

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

struct ContentView: View {
  @State var capitalizedText: String = ""
  var body: some View {
    TextField(
      "placeholder",
      value: $capitalizedText,
      formatter: CapitalizedFormatter()
    )
  }
}

onCommit示例:

struct ContentView: View {
  @State var capitalizedText: String = ""
  var body: some View {
    TextField(
      "Placeholder",
      text: $capitalizedText,
      onCommit: { self.capitalizedText = self.capitalizedText.uppercased() }
    )
  }
}

如果您想要连续的文本值,则使用绑定在设置程序中拦截新值,然后格式化它们,然后在getter中发出该值:

final class Model: ObservableObject {
  @Published var capitalizedText = ""
  func set(text: String) {
    capitalizedText = text.uppercased()
  }
}

struct ContentView: View {
  @ObservedObject var model: Model
  var textBinding: Binding<String>
  init() {
    let model = Model()
    self.textBinding = .init(
      get: { model.capitalizedText },
      set: { model.set(text: $0) }
    )
    self.model = model
  }

  var body: some View {
    TextField(
      "Placeholder",
      text: textBinding
    )
  }
}