如何移动到 SwiftUI 中的下一个 TextField? [英] How to move to next TextField in SwiftUI?

查看:33
本文介绍了如何移动到 SwiftUI 中的下一个 TextField?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

Using Swift5.1.2, iOS13.2, Xcode-11.2,

在 Stackview 中有几个 TextField,我想在用户在第一个 TextField 中输入 x 数量的字符后立即移动到下一个 TextField.

Having several TextFields in a Stackview, I would like to move to the next TextField as soon as the user types x-amount of characters into the first TextField.

通过此链接,我可以识别 TextField 条目何时达到 x 字符数.但是,我不知道如何让 firstResponder 跳转到我的 StackView 中的第二个 TextField.

With this link, I achieve to recognise when a TextField entry has reached x-amount of characters. However, I do not know how to make the firstResponder jump to a second TextField inside my StackView.

SwiftUI 是否有解决方案?

Is there a solution to this with SwiftUI ?

推荐答案

我已经采纳了@Philip Borbon 的回答并对其进行了一些清理.我删除了很多自定义内容,并保留在最低限度,以便更容易地了解需要什么.

I've taken @Philip Borbon answer and cleaned it up a little bit. I've removed a lot of the customization and kept in the bare minimum to make it easier to see what's required.

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 ?? ""
        }
    }
}

这篇关于如何移动到 SwiftUI 中的下一个 TextField?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆