我有一个文本视图列表,我想在按下一个键后切换焦点.我有一个 struct 体,它代表我的文本字段数据:

struct WordEntry : BaseIndexStruct, Identifiable, Equatable, Hashable{
    let id = UUID()
    var word : String = ""
    var index : Int
    
    init(index: Int) {
        self.index = index
    }
}

然后我有了一个控制焦点的文本字段的视图,我在这里添加了一条print语句来查看word.index==Focus!实际上从来都是真的.它确实变成了真的,但是设置isFocused没有影响,在打印期间它仍然是假的.

struct SolvedField: View {
    @State var word: WordEntry
    @FocusState var isFocused: Bool
    @Binding var focus: Int?
    var nextFocus: (Int) -> Void

    var body: some View {
        TextField("", text: $word.word)
            .onChange(of: focus, perform: { newValue in
                if(focus != nil){
                    self.isFocused = word.index == focus!
                    print("index \(word.index), focus \(focus!), isfocused: \(self.isFocused) should be focused \(word.index == focus!)")
                }
            })
            .focused(self.$isFocused)
            .submitLabel(.next)
            .onSubmit {
                isFocused = false
                self.nextFocus(word.index)
            }
    }
}

然后是包含单词条目列表的视图,这些单词条目随后被显示为文本字段控件.

    struct SolvedLettersLine: View {
        @State var words = [WordEntry(index: 0), WordEntry(index: 1), WordEntry(index: 2), WordEntry(index: 3)]
        @State var focus : Int?
        
        var body: some View {
            VStack(spacing:10){
                Group{
                    ForEach(words) { word in
                        SolvedField(word: word, focus: $focus, nextFocus:{
                            focus = $0 + 1
                        })
        

            }
        }
   }
}

不幸的是,我完全被困在如何让iOS将Textfield焦点切换到工作上,有人知道吗?

推荐答案

SolvedLettersLine中应该只有一个@FocusState,这表示当前关注的是哪个字段.这应该是类型Int?.

现在可以使用focused(_:equals:)修改器来控制文本字段的焦点.

然后,您可以将这@FocusState作为FocusState.Binding传递给SolvedField,类似于将常规的@State传递给@Binding.

struct SolvedField: View {
    // side note: word should not be a @State!
    @Binding var word: WordEntry

    @FocusState.Binding var focus: Int?
    let nextFocus: () -> Void

    var body: some View {
        TextField("", text: $word.word)
            .focused($focus, equals: word.index)
            .submitLabel(.next)
            .onSubmit {
                nextFocus()
            }
    }
}

struct SolvedLettersLine: View {
    @State var words = [WordEntry(index: 0), WordEntry(index: 1), WordEntry(index: 2), WordEntry(index: 3)]
    @FocusState var focus: Int?
    
    var body: some View {
        VStack(spacing:10){
            ForEach($words) { $word in
                SolvedField(word: $word, focus: $focus) { 
                    focus? += 1
                }
            }
        }
    }
}

Swift相关问答推荐

为什么不能使用actor作为AsyncSequence中的状态机类型?

为什么在Swift属性Wrapper中需要类型注释?

无法创建MKAssociateRegion对象

找出touch 点的屏幕亮度

字符串和整数格式的for循环,帮忙!

暂停我的 AR 会话并清除变量和锚点的功能

子视图未在父视图 SwiftUI 中触发禁用状态更新

使用 Async-Await 和 Vapor-Fluent 创建 CRUD 函数 - Swift 5.6

SwiftUI 动画的范围

来自数据的 SwiftUI 图像

(SwiftLint)如果有正文,如何编写规则(可能是自定义),在{之后总是\n(换行)?

swift中的SequenceType和CollectionType有什么区别?

在swift 3中将文件保存在文档目录中?

更新我的 pod 导致 GoogleDataTransport Umbrella 标头出现错误

在 Swift 4 中,如何删除基于块的 KVO 观察者?

Swift 自定义字体 Xcode

如何使用 swift 将 Images.xcassets 中的图像加载到 UIImage 中

自定义 MKAnnotation 标注视图?

更改在变量的 willSet 块中设置的值

在 xcode8 中找不到 ModuleName-Swift.h 文件