问题描述
使用 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?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!