SwiftUI是否有类似可可的东西;s nextKeyView,这样我就可以指定当我点击tab时TextView获取光标的确切顺序了?

SwiftUI是否有类似可可的东西;s nextKeyView,这样我就可以指定当我点击tab时TextView获取光标的确切顺序了?,swiftui,uitextfield,nstextfield,Swiftui,Uitextfield,Nstextfield,假设我有6个文本字段排列在一个网格中,有3列2行。我们将通过它们在该网格中的X,Y位置来引用它们,从左上角文本字段中的1,1开始,从右下角的3,2开始 当我运行这个程序时,我将光标放在文本字段1,1中并输入一个值。我点击tab,光标转到2,1;然后是3,1;然后是1,2;然后是2,2;最后是3,2 光标水平移动穿过第一行,然后穿过第二行,依此类推 不过,我需要改变顺序 我需要它沿着第1列前进,然后移到第2列,然后再移到第3列 在Cocoa编程中,可以使用nextKeyView指定顺序 Swift

假设我有6个文本字段排列在一个网格中,有3列2行。我们将通过它们在该网格中的X,Y位置来引用它们,从左上角文本字段中的1,1开始,从右下角的3,2开始

当我运行这个程序时,我将光标放在文本字段1,1中并输入一个值。我点击tab,光标转到2,1;然后是3,1;然后是1,2;然后是2,2;最后是3,2

光标水平移动穿过第一行,然后穿过第二行,依此类推

不过,我需要改变顺序

我需要它沿着第1列前进,然后移到第2列,然后再移到第3列

在Cocoa编程中,可以使用nextKeyView指定顺序

SwiftUI中有类似的功能吗

我希望我能把他们分组在下面的VSTACK中,得到我想要的行为,但这不起作用。我还尝试将列对放入
组{…}
中,但不起作用

struct ContentView: View {
@State private var oneone = ""
@State private var onetwo = ""
@State private var twoone = ""
@State private var twotwo = ""
@State private var threeone = ""
@State private var threetwo = ""

var body: some View {
    HStack {
        VStack {
            TextField("1,1", text: $oneone)

            TextField("1,2", text: $onetwo)
        }
        
        VStack {
            TextField("2,1", text: $twoone)

            TextField("2,2", text: $twotwo)
        }

        VStack {
            TextField("3,1", text: $threeone)

            TextField("3,2", text: $threetwo)

        }
    }
}

}SwiftUI还没有内置此功能,但Swift有。要在SwiftUI中执行此操作,请创建符合UIViewRepresentable的自定义文本字段,以便在文本字段中使用becomeFirstResponder功能。以下是我在项目中是如何做到这一点的。此示例有几个您可能不需要的可选变量。请随意调整它为您工作

struct CustomTextField: UIViewRepresentable
{
  @Binding var text: String
  @Binding var selectedField: Int
  @Binding var secure: Bool // Optional
  var placeholder: String = ""
  
  var tag: Int
  var keyboardType: UIKeyboardType = .asciiCapable // Optional
  var returnKey: UIReturnKeyType = .next // Optional
  var correctionType: UITextAutocorrectionType = .default // Optional
  var capitalizationType: UITextAutocapitalizationType = .sentences // Optional
  
  func makeUIView(context: UIViewRepresentableContext<CustomTextField>) -> UITextField
  {
    let textField = UITextField(frame: .zero)
    textField.delegate = context.coordinator
    textField.keyboardType = keyboardType
    textField.returnKeyType = returnKey
    textField.autocorrectionType = correctionType
    textField.autocapitalizationType = capitalizationType
    textField.tag = tag
    textField.isSecureTextEntry = secure
    textField.placeholder = placeholder
    return textField
  }
  
  func makeCoordinator() -> CustomTextField.Coordinator
  {
    return Coordinator(text: $text, secure: $secure)
  }
  
  func updateUIView(_ uiView: UITextField, context: UIViewRepresentableContext<CustomTextField>)
  {
    uiView.text = text
    uiView.isSecureTextEntry = secure
    context.coordinator.newSelection = { newSelection in
      DispatchQueue.main.async {
        self.selectedField = newSelection
      }
    }
    
    if uiView.tag == self.selectedField
    {
      uiView.becomeFirstResponder()
    }
  }
  
  class Coordinator: NSObject, UITextFieldDelegate
  {
    @Binding var text: String
    @Binding var secure: Bool
    var newSelection: (Int) -> () = { _ in }
    
    init(text: Binding<String>, secure: Binding<Bool>)
    {
      _text = text
      _secure = secure
    }
    
    func textFieldDidChangeSelection(_ textField: UITextField)
    {
      DispatchQueue.main.async {
        self.text = textField.text ?? ""
      }
    }
    
    func textFieldDidBeginEditing(_ textField: UITextField)
    {
      self.newSelection(textField.tag)
    }
    
    func textFieldShouldReturn(_ textField: UITextField) -> Bool
    {
      if textField.returnKeyType == .done
      {
        textField.resignFirstResponder()
      }
      else
      {
        self.newSelection(textField.tag + 1)
      }
      return true
    }
  }
}
struct ContentView: View {
    @State private var oneOne = ""
    @State private var oneTwo = ""
    @State private var twoOne = ""
    @State private var twoTwo = ""
    @State private var threeOne = ""
    @State private var threeTwo = ""
    @State private var selectedField: Int = 0
    @State private var fieldsSecure: Bool = false

var body: some View {
    HStack {
        VStack {
            CustomTextField(
             text: $oneOne, 
             selectedField: $selectedField, 
             secure: $fieldsSecure, 
             placeholder: "1, 1", 
             tag: 1, 
             keyboardType: .asciiCapable, 
             returnKey: .done, 
             correctionType: .yes, 
             capitalizationType: .words)

            CustomTextField(
             text: $oneTwo, 
             selectedField: $selectedField, 
             secure: $fieldsSecure, 
             placeholder: "1, 2", 
             tag: 4, 
             keyboardType: .asciiCapable, 
             returnKey: .done, 
             correctionType: .yes, 
             capitalizationType: .words)
        }
        
        VStack {
            CustomTextField(
             text: $twoOne, 
             selectedField: $selectedField, 
             secure: $fieldsSecure, 
             placeholder: "2, 1", 
             tag: 2, 
             keyboardType: .asciiCapable, 
             returnKey: .done, 
             correctionType: .yes, 
             capitalizationType: .words)

            CustomTextField(
             text: $twoTwo, 
             selectedField: $selectedField, 
             secure: $fieldsSecure, 
             placeholder: "2, 2", 
             tag: 5, 
             keyboardType: .asciiCapable, 
             returnKey: .done, 
             correctionType: .yes, 
             capitalizationType: .words)
        }

        VStack {
            CustomTextField(
             text: $threeOne, 
             selectedField: $selectedField, 
             secure: $fieldsSecure, 
             placeholder: "3, 1", 
             tag: 3, 
             keyboardType: .asciiCapable, 
             returnKey: .done, 
             correctionType: .yes, 
             capitalizationType: .words)

            CustomTextField(
             text: $threeTwo, 
             selectedField: $selectedField, 
             secure: $fieldsSecure, 
             placeholder: "3, 2", 
             tag: 6, 
             keyboardType: .asciiCapable, 
             returnKey: .done, 
             correctionType: .yes, 
             capitalizationType: .words)
        }
    }
}