在MacOS应用程序的SwiftUI中管理自动建议字段中的焦点

在MacOS应用程序的SwiftUI中管理自动建议字段中的焦点,macos,swiftui,focus,Macos,Swiftui,Focus,我想在MacOS应用程序的SwiftUI中构建一个“自动建议字段”。 我的第一次尝试效果很好。 我面临的问题是如何管理焦点,以实现平滑的键盘(仅)处理 如果用户在文本字段中输入了超过1个字符,将显示一个包含建议的列表。此时,用户可以用鼠标选择一个。 我想要的是,用户仍然可以编辑文本字段,在文本字段中使用光标左键和光标右键进行导航(这种情况下),另外使用光标上下导航列表,并选择一个条目,例如空格或回车 我在NSViewRepresentable中包装了一个NSTextField,并使用了NSTex

我想在MacOS应用程序的SwiftUI中构建一个“自动建议字段”。
我的第一次尝试效果很好。
我面临的问题是如何管理焦点,以实现平滑的键盘(仅)处理

如果用户在文本字段中输入了超过1个字符,将显示一个包含建议的列表。此时,用户可以用鼠标选择一个。
我想要的是,用户仍然可以编辑文本字段,在文本字段中使用光标左键和光标右键进行导航(这种情况下),另外使用光标上下导航列表,并选择一个条目,例如空格或回车


我在NSViewRepresentable中包装了一个NSTextField,并使用了NSTextFieldDelegate。您可以找到我的GitHub示例


完美的解决方案!tnx,在witch许可下你发布了演示吗?公共领域。我添加了一个许可证文件。谢谢@stephanhechels!我已经找了很长时间了。我欠你一大笔钱。但是,我注意到它创建了太多的窗口实例,其中一些实例位于屏幕的左下角。我可以试着自己解决这个问题,但如果你有任何可以帮助的指针。
struct TestSearchField2: View {
  var body: some View {
    VStack{
      SearchField2()
    } .frame(width: 400, height: 400, alignment: .center)
  }
}

enum SuggestionListStatus {
  case off
  case on
  case accepted
}

struct SearchField2: View {
  let allSuggestions =  ["michael Schneider","thomas mueller","joachim Oster","Dennis mueller","Michael Carter","frank 1","frank 2","frank 3","frank 4","frank 5"]
  @State var input = ""
  @State var showList : SuggestionListStatus = .off
  @State var selected = ""

  var body: some View {
    TextField("input Data", text: $input)
    .cornerRadius(5.0)
      .overlay(SuggestionList2(suggestionListStatus: $showList, selected: $input, suggestions: allSuggestions.filter {$0.contains(input)}))
    .onChange(of: input, perform: { value in
      if showList == .accepted {
        showList = .off}
      else if input.count >= 2 {
        print(
        allSuggestions.filter {$0.contains(input)})
        showList = .on
      } else {
        showList = .off
      }
    })
  }
}


struct SuggestionList2: View {
  @Binding var suggestionListStatus : SuggestionListStatus
  @Binding var selected : String
  @State var selection : String? = "Michael"
  var suggestions : [String] 


  var body: some View {
    if suggestionListStatus == .on {
      VStack{
        List(suggestions, id: \.self, selection: $selection){ s in
          Text(s).onTapGesture {
            print("Pressed; \(s)")
            selected = s
            suggestionListStatus = .accepted
          }
        }
        Text("Debug setected: \(selection ?? "nothing selected")").font(.footnote)
    }
    .frame(width: 200, height: 150, alignment: .leading)
    .offset(x: 0, y: 100)
    }
  }
}