【问题标题】:macOS SwiftUI: tab through focus in vertical rather than horizontal directionmacOS SwiftUI:通过焦点在垂直方向而不是水平方向上的制表符
【发布时间】:2021-07-03 05:04:38
【问题描述】:

我有一个 macOS SwiftUI 应用程序,其中有几个 TextField 布局在 LazyHGrid 中。它们分为三列,每列大约有 10 个文本字段。如果在TextField 中只有一列制表符会发生预期的事情:它会在列表中垂直向下进行,从而允许用户以垂直顺序输入文本。但是,如果有两列或更多列,则 Tab 键会从左到右移动焦点,在移动到下一行之前遍历整行。

我希望焦点从上到下移动,在移动到下一列之前完成一整列。有谁知道如何做到这一点?到目前为止,我尝试过的任何方法都没有奏效。

这是一些显示问题的代码

import SwiftUI

struct ContentView: View {
    @State private var input = [String](repeating: "", count: 4)

    var body: some View {
        let rows = [GridItem(.fixed(20), alignment: .leading),
                    GridItem(.fixed(20), alignment: .leading),
                    GridItem(.fixed(20), alignment: .leading),
        ]
    
        LazyHGrid(rows: rows) {
            Group {
                Text("Column 1")
                TextField("", text: $input[0])
                TextField("", text: $input[1])
            }.frame(width: 100)
            Group {
                Text("Column 2")
                TextField("", text: $input[2])
                TextField("", text: $input[3])
            }.frame(width: 100)
        }
    }
}

我尝试过的一些方法不起作用:

  • 改用LazyVGrid。这也有同样的问题。
  • 在具有TextField 的列之间添加一个空列。这对焦点顺序没有影响。
  • Group 上创建focusScope

【问题讨论】:

标签: swift macos swiftui


【解决方案1】:

好的,我找到了一种可行的方法。它不适用于我的应用程序,因为我的应用程序太复杂,并且当我使用这种方法时编译器无法对其进行类型检查。希望这是 Apple 在未来版本中改进的地方。但是我在这里发布解决方案,以防有人发现它有用。我说它“有点工作”的原因是因为它不能正确响应 tab 键,只有 enter 键。这似乎是一个 Apple 错误。

基本思路如下

struct ContentView: View {
    @State private var input = [String](repeating: "", count: 4)
    @FocusState private var focus: Int?
    
    var body: some View {
        let rows = [GridItem(.fixed(20), alignment: .leading),
                    GridItem(.fixed(20), alignment: .leading),
                    GridItem(.fixed(20), alignment: .leading)
        ]
        
        LazyHGrid(rows: rows) {
            Group {
                Text("Column 1")
                TextField("", text: $input[0], onCommit: { updateFocus() })
                    .focused($focus, equals: 0)
                    
                TextField("", text: $input[1], onCommit: { updateFocus() })
                    .focused($focus, equals: 1)
            }.frame(width: 100)
            Group {
                Text("Column 2")
                TextField("", text: $input[2], onCommit: { updateFocus() })
                    .focused($focus, equals: 2)
                TextField("", text: $input[3], onCommit: { updateFocus() })
                    .focused($focus, equals: 3)
            }.frame(width: 100)
        }
    }
    
    func updateFocus() {
        if focus == nil {
            focus = 0
        } else {
            focus = (focus! + 1) % 4
        }
    }
}

【讨论】:

    猜你喜欢
    • 2022-11-15
    • 2012-09-11
    • 2016-11-21
    • 2012-04-20
    • 1970-01-01
    • 2012-02-25
    • 2012-12-27
    • 2014-10-10
    • 2015-03-23
    相关资源
    最近更新 更多