Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/magento/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何在SwiftUI中移动到下一个文本字段?_Swift_Textfield_Swiftui_First Responder - Fatal编程技术网

如何在SwiftUI中移动到下一个文本字段?

如何在SwiftUI中移动到下一个文本字段?,swift,textfield,swiftui,first-responder,Swift,Textfield,Swiftui,First Responder,使用Swift5.1.2、iOS13.2、Xcode-11.2、 Stackview中有多个文本字段,我希望在用户在第一个文本字段中键入x个字符后立即转到下一个文本字段 使用,我可以识别文本字段条目何时达到x个字符的数量。但是,我不知道如何让第一响应者跳转到StackView中的第二个文本字段 使用SwiftUI有解决方案吗?试试这个: import SwiftUI struct ResponderTextField: UIViewRepresentable { typealias

使用Swift5.1.2、iOS13.2、Xcode-11.2、

Stackview中有多个文本字段,我希望在用户在第一个文本字段中键入x个字符后立即转到下一个文本字段

使用,我可以识别文本字段条目何时达到x个字符的数量。但是,我不知道如何让第一响应者跳转到StackView中的第二个文本字段

使用SwiftUI有解决方案吗?

试试这个:

import SwiftUI

struct ResponderTextField: UIViewRepresentable {

    typealias TheUIView = UITextField
    var isFirstResponder: Bool
    var configuration = { (view: TheUIView) in }

    func makeUIView(context: UIViewRepresentableContext<Self>) -> TheUIView { TheUIView() }
    func updateUIView(_ uiView: TheUIView, context: UIViewRepresentableContext<Self>) {
        _ = isFirstResponder ? uiView.becomeFirstResponder() : uiView.resignFirstResponder()
        configuration(uiView)
    }
}


struct ContentView: View {
    @State private var entry = ""
    @State private var entry2 = ""

    let characterLimit = 6

    var body: some View {
        VStack {
            TextField("hallo", text: $entry)
                .disabled(entry.count > (characterLimit - 1))

            ResponderTextField(isFirstResponder: entry.count > (characterLimit - 1)) { uiView in
                uiView.placeholder = "2nd textField"
            }
        }
    }
}
导入快捷界面
struct ResponderTextField:UIViewRepresentable{
类型别名TheUIView=UITextField
var是第一响应者:Bool
var配置={(视图:TheUIView)in}
func makeUIView(上下文:UIViewRepresentableContext)->TheUIView{TheUIView()}
func updateUIView(uiView:TheUIView,context:UIViewRepresentableContext){
_=isFirstResponder?uiView.becomeFirstResponder():uiView.resignFirstResponder()
配置(uiView)
}
}
结构ContentView:View{
@国家私有var entry=“”
@国家私有变量entry2=“”
设characterLimit=6
var body:一些观点{
VStack{
TextField(“你好”,text:$entry)
.disabled(entry.count>(characterLimit-1))
ResponderTextField(isFirstResponder:entry.count>(characterLimit-1)){uiView in
uiView.placeholder=“第二个文本字段”
}
}
}
}

我可以通过内省库完成这项工作:

@State private var passcode=“”
HStack{
文本字段(“,文本:self.$passcode)
.introspectTextField{textField in
如果self.passcode.count>=1{
textField.resignFirstResponder()辞职
}否则,如果self.passcode.count<1{
textField.becomeFirstResponder()
}
}
文本字段(“,文本:self.$passcode)
.introspectTextField{textField in
如果self.passcode.count>=2
textField.resignFirstResponder()辞职
}否则,如果self.passcode.count<2{
textField.becomeFirstResponder()
}
}
}

我可能因为试图复制和粘贴我的代码而把实现搞砸了,但您已经了解了它的工作原理。

我正在使用
UITextField
UIViewRepresentable
来实现这一点

定义每个文本字段的
tag
,并声明一个布尔值列表,其中返回键
fieldFocus
的可用文本字段数相同,它将根据当前索引/标记跟踪下一个要聚焦的文本字段

用法:

导入快捷界面
结构示例:视图{
@State var firstName:String=“”
@状态变量lastName:String=“”
@状态变量fieldFocus=[false,false]
var body:一些观点{
VStack{
基特斯菲尔德(
标签:“名字”,
文本:$firstName,
聚焦:$fieldFocus,
returnKeyType:。下一步,
标签:0
)
.padding()
.框架(高度:48)
基特斯菲尔德(
标签:“姓氏”,
text:$lastName,
聚焦:$fieldFocus,
returnKeyType:。完成,
标签:1
)
.padding()
.框架(高度:48)
}
}
}
UIViewRepresentable
中的
UITextField

导入快捷界面
结构KitTextField:UIViewRepresentable{
让标签:字符串
@绑定变量文本:字符串
变量可聚焦:绑定?=nil
var isSecureTextEntry:绑定?=nil
var returnKeyType:UIReturnKeyType=.default
var autocapitalizationType:UITextAutocapitalizationType=.none
变量keyboardType:UIKeyboardType=.default
var textContentType:UITextContentType?=nil
变量标记:Int?=nil
var inputAccessoryView:UIToolbar?=nil
var onCommit:(()->Void)?=无
func makeUIView(上下文:context)->UITextField{
设textField=UITextField(帧:.0)
textField.delegate=context.coordinator
textField.placeholder=标签
textField.returnKeyType=returnKeyType
textField.autocapitalizationType=autocapitalizationType
textField.keyboardType=键盘类型
textField.issecurettentry=issecurettentry?.wrappedValue??false
textField.textContentType=textContentType
textField.textAlignment=.left
如果let tag=tag{
textField.tag=tag
}
textField.inputAccessoryView=inputAccessoryView
textField.addTarget(context.coordinator,action:#选择器(coordinator.textFieldDidChange(:)),for:.editingChanged)
textField.setContentCompressionResistancePriority(.defaultLow,用于:。水平)
返回文本字段
}
func updateUIView(uiView:UITextField,context:context){
uiView.text=文本
uiView.IsSecureTextry=IsSecureTextry?.wrappedValue??错误
如果let focusable=focusable?.wrappedValue{
var resignResponder=true
对于focusable.enumerated()中的(索引,聚焦){
如果uiView.tag==index&&focused{
uiView.becomeFirstResponder()
resignResponder=false
打破
}
}
如果辞职响应者{
uiView.resignFirstResponder()的辞职
}
}
}
func makeCoordinator()->Coordinator{
协调员(自我)
}
最后一节课坐标
              @State private var passcode = ""

              HStack {
                  TextField("", text: self.$passcode)
                    .introspectTextField { textField in
                      if self.passcode.count >= 1 {
                        textField.resignFirstResponder()
                      } else if self.passcode.count < 1 {
                        textField.becomeFirstResponder()
                      }
                  }
                  TextField("", text: self.$passcode)
                    .introspectTextField { textField in
                      if self.passcode.count >= 2
                        textField.resignFirstResponder()
                      } else if self.passcode.count < 2 {
                        textField.becomeFirstResponder()
                      }
                  }
              }
struct ContentView: View {
    @State private var street: String = ""
    @State private var city: String = ""
    @State private var country: String = ""

    @FocusState private var focusedField: Field?

    var body: some View {
        NavigationView {
            VStack {
                TextField("Street", text: $street)
                    .focused($focusedField, equals: .street)
                TextField("City", text: $city)
                    .focused($focusedField, equals: .city)
                TextField("Country", text: $country)
                    .focused($focusedField, equals: .country)
            }
            .toolbar {
                ToolbarItem(placement: .keyboard) {
                    Button(action: focusPreviousField) {
                        Image(systemName: "chevron.up")
                    }
                    .disabled(!canFocusPreviousField()) // remove this to loop through fields
                }
                ToolbarItem(placement: .keyboard) {
                    Button(action: focusNextField) {
                        Image(systemName: "chevron.down")
                    }
                    .disabled(!canFocusNextField()) // remove this to loop through fields
                }
            }
        }
    }
}
extension ContentView {
    private enum Field: Int, CaseIterable {
        case street, city, country
    }
    
    private func focusPreviousField() {
        focusedField = focusedField.map {
            Field(rawValue: $0.rawValue - 1) ?? .country
        }
    }

    private func focusNextField() {
        focusedField = focusedField.map {
            Field(rawValue: $0.rawValue + 1) ?? .street
        }
    }
    
    private func canFocusPreviousField() -> Bool {
        guard let currentFocusedField = focusedField else {
            return false
        }
        return currentFocusedField.rawValue > 0
    }

    private func canFocusNextField() -> Bool {
        guard let currentFocusedField = focusedField else {
            return false
        }
        return currentFocusedField.rawValue < Field.allCases.count - 1
    }
}
struct CustomTextfield: UIViewRepresentable {
    let label: String
    @Binding var text: String
    
    var focusable: Binding<[Bool]>? = nil
    
    var returnKeyType: UIReturnKeyType = .default
    
    var tag: Int? = nil
    
    var onCommit: (() -> Void)? = nil
    
    func makeUIView(context: Context) -> UITextField {
        let textField = UITextField(frame: .zero)
        textField.placeholder = label
        textField.delegate = context.coordinator
        
        textField.returnKeyType = returnKeyType
        
        if let tag = tag {
            textField.tag = tag
        }
        
        return textField
    }
    
    func updateUIView(_ uiView: UITextField, context: Context) {
        uiView.text = text
        
        if let focusable = focusable?.wrappedValue {
            var resignResponder = true
            
            for (index, focused) in focusable.enumerated() {
                if uiView.tag == index && focused {
                    uiView.becomeFirstResponder()
                    resignResponder = false
                    break
                }
            }
            
            if resignResponder {
                uiView.resignFirstResponder()
            }
        }
    }
    
    func makeCoordinator() -> Coordinator {
        Coordinator(self)
    }
    
    final class Coordinator: NSObject, UITextFieldDelegate {
        let parent: CustomTextfield
        
        init(_ parent: CustomTextfield) {
            self.parent = parent
        }
        
        func textFieldDidBeginEditing(_ textField: UITextField) {
            guard var focusable = parent.focusable?.wrappedValue else { return }
            
            for i in 0...(focusable.count - 1) {
                focusable[i] = (textField.tag == i)
            }
            parent.focusable?.wrappedValue = focusable
        }
        
        func textFieldShouldReturn(_ textField: UITextField) -> Bool {
            guard var focusable = parent.focusable?.wrappedValue else {
                textField.resignFirstResponder()
                return true
            }
            
            for i in 0...(focusable.count - 1) {
                focusable[i] = (textField.tag + 1 == i)
            }
            
            parent.focusable?.wrappedValue = focusable
            
            if textField.tag == focusable.count - 1 {
                textField.resignFirstResponder()
            }
            
            return true
        }
        
        @objc func textFieldDidChange(_ textField: UITextField) {
            parent.text = textField.text ?? ""
        }
    }
}