选择了 SwiftUI 列表行而不是聚焦于 TextField

问题描述 投票:0回答:1

问题

  • 我有一个带有选择绑定的列表视图,一个带有两个文本字段的自定义 rowView。
  • 当我单击文本字段时,列表行将被选中,而不是文本字段获得焦点。
  • 我的目标是 macOS 12

可重现的示例

struct DemoView: View {
    @ObservedObject var model: DemoModel

    var body: some View {
        List(selection: self.$model.selectedRows) {
            DisclosureGroup(isExpanded: self.$model.isExpanded, content: {
                ForEach(self.model.models) { rowModel in
                    RowView(rowModel: rowModel)
                        .contentShape(Rectangle())
                        .swipeActions {
                            Button("Swipe") {
                            }
                        }
                }
                .onMove { fromIndices, toIndex in
                    self.model.models.move(fromOffsets: fromIndices, toOffset: toIndex)
                }
            }, label: {
                HStack(alignment: .center) {
                    Text("Title")
                    Spacer()
                    Button("Add row", systemImage: "plus") {
                        let rowModel = RowModel()
                        self.model.models.append(rowModel)
                    }
                }
            })
        }
    }
}

class DemoModel: ObservableObject {
    @Published var models: [RowModel]
    @Published var isExpanded: Bool
    @Published var selectedRows: Set<UUID>

    init() {
        let one = RowModel()
        let two = RowModel()
        self.models = [one, two]
        self.isExpanded = true
        self.selectedRows = Set()
    }
}

enum CustomFocusState {
    case textFieldOne, textFieldTwo
}

struct RowView: View {
    @ObservedObject var rowModel: RowModel
    @FocusState var focuseState: CustomFocusState?

    var body: some View {
        HStack {
            TextField("Enter text", text: self.$rowModel.text)
                .textFieldStyle(.roundedBorder)
                .padding()
                .focusable()
                .focused($focuseState, equals: .textFieldOne)
                .onTapGesture {
                    self.focuseState = .textFieldOne
                    print("tapped textFieldOne")
                }
            TextField("Enter text", text: self.$rowModel.text2)
                .textFieldStyle(.roundedBorder)
                .padding()
                .focusable()
                .focused($focuseState, equals: .textFieldTwo)
                .onTapGesture {
                    self.focuseState = .textFieldTwo
                    print("tapped textFieldTwo")
                }
        }
    }
}

class RowModel: ObservableObject, Identifiable {
    @Published var text: String
    @Published var text2: String
    var id: UUID

    init() {
        self.text = ""
        self.text2 = ""
        self.id = UUID()
    }
}

extension RowModel: Hashable {
    static func == (lhs: RowModel, rhs: RowModel) -> Bool {
        lhs.id == rhs.id
    }

    func hash(into hasher: inout Hasher) {
        hasher.combine(self.id)
    }
}

当前行为

  • 第一次单击时,该行被选中,仅在第二次单击时,文本字段才会获得焦点

预期行为

  • 如果单击文本字段,则文本字段应该获得焦点
  • 如果单击的是文本字段之外的行,则应选择该行
swift macos swiftui swiftui-list
1个回答
0
投票

尝试从文本字段中删除 .focusable()。

© www.soinside.com 2019 - 2024. All rights reserved.