首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何移动到下一个TextField在SwiftUI?

如何移动到下一个TextField在SwiftUI?
EN

Stack Overflow用户
提问于 2019-11-02 16:44:24
回答 9查看 11.4K关注 0票数 16

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

在Stackview中有几个TextFields,当用户在第一个TextField中输入x-数量的字符时,我想移到下一个TextField。

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

SwiftUI有解决这个问题的方法吗?

EN

回答 9

Stack Overflow用户

回答已采纳

发布于 2021-06-19 05:00:21

iOS 15+

使用@FocusState

在iOS 15之前

“我接受了”菲利普·波旁的回答,并把它弄干净了一点。我已经删除了许多定制,并保持在最低限度,以使它更容易看到什么是必需的。

代码语言:javascript
复制
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 ?? ""
        }
    }
}
票数 6
EN

Stack Overflow用户

发布于 2020-10-06 03:11:03

我正在使用UITextFieldUIViewRepresentable来实现这一点。

定义每个文本字段的tag,并声明一个具有相同数量可用文本字段的布尔列表,该列表将以返回键fieldFocus为焦点,这将跟踪下一个基于当前索引/标记的文本字段。

用法:

代码语言:javascript
复制
import SwiftUI

struct Sample: View {
    @State var firstName: String = ""
    @State var lastName: String = ""
    
    @State var fieldFocus = [false, false]
    
    var body: some View {
        VStack {
            KitTextField (
                label: "First name",
                text: $firstName,
                focusable: $fieldFocus,
                returnKeyType: .next,
                tag: 0
            )
            .padding()
            .frame(height: 48)
            
            KitTextField (
                label: "Last name",
                text: $lastName,
                focusable: $fieldFocus,
                returnKeyType: .done,
                tag: 1
            )
            .padding()
            .frame(height: 48)
        }
    }
}

UITextField in UIViewRepresentable

代码语言:javascript
复制
import SwiftUI

struct KitTextField: UIViewRepresentable {
    let label: String
    @Binding var text: String
    
    var focusable: Binding<[Bool]>? = nil
    var isSecureTextEntry: Binding<Bool>? = nil
    
    var returnKeyType: UIReturnKeyType = .default
    var autocapitalizationType: UITextAutocapitalizationType = .none
    var keyboardType: UIKeyboardType = .default
    var textContentType: UITextContentType? = nil
    
    var tag: Int? = nil
    var inputAccessoryView: UIToolbar? = nil
    
    var onCommit: (() -> Void)? = nil
    
    func makeUIView(context: Context) -> UITextField {
        let textField = UITextField(frame: .zero)
        textField.delegate = context.coordinator
        textField.placeholder = label
        
        textField.returnKeyType = returnKeyType
        textField.autocapitalizationType = autocapitalizationType
        textField.keyboardType = keyboardType
        textField.isSecureTextEntry = isSecureTextEntry?.wrappedValue ?? false
        textField.textContentType = textContentType
        textField.textAlignment = .left
        
        if let tag = tag {
            textField.tag = tag
        }
        
        textField.inputAccessoryView = inputAccessoryView
        textField.addTarget(context.coordinator, action: #selector(Coordinator.textFieldDidChange(_:)), for: .editingChanged)
        
        textField.setContentCompressionResistancePriority(.defaultLow, for: .horizontal)
        
        return textField
    }
    
    func updateUIView(_ uiView: UITextField, context: Context) {
        uiView.text = text
        uiView.isSecureTextEntry = isSecureTextEntry?.wrappedValue ?? false
        
        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 control: KitTextField
        
        init(_ control: KitTextField) {
            self.control = control
        }
        
        func textFieldDidBeginEditing(_ textField: UITextField) {
            guard var focusable = control.focusable?.wrappedValue else { return }
            
            for i in 0...(focusable.count - 1) {
                focusable[i] = (textField.tag == i)
            }
            
            control.focusable?.wrappedValue = focusable
        }
        
        func textFieldShouldReturn(_ textField: UITextField) -> Bool {
            guard var focusable = control.focusable?.wrappedValue else {
                textField.resignFirstResponder()
                return true
            }
            
            for i in 0...(focusable.count - 1) {
                focusable[i] = (textField.tag + 1 == i)
            }
            
            control.focusable?.wrappedValue = focusable
            
            if textField.tag == focusable.count - 1 {
                textField.resignFirstResponder()
            }
            
            return true
        }
        
        func textFieldDidEndEditing(_ textField: UITextField) {
            control.onCommit?()
        }
        
        @objc func textFieldDidChange(_ textField: UITextField) {
            control.text = textField.text ?? ""
        }
    }
}

票数 8
EN

Stack Overflow用户

发布于 2021-06-08 17:46:38

iOS 15

今年,苹果推出了一个新的修饰符,同时还推出了一个名为@FocusState的新包装器,用于控制键盘和聚焦键盘(又名firstResponder)的状态。

下面是如何在textFields上迭代的示例:

此外,您还可以查看这个答案,了解如何制作textField第一个响应程序或辞职以隐藏键盘,并了解如何将此枚举绑定到textFields。

票数 5
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/58673159

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档