macOS 上可搜索修饰符的键盘命令

Den*_* L. 11 macos swift swiftui

编辑

\n

现在有针对 iOS 17 及以上版本的解决方案

\n
\n

原帖

\n

iOS 15 SwiftUI 3.0 中引入的新功能之一是.searchable视图修改器。下面是一个简单的例子来说明它是如何工作的。我想添加\xe2\x8c\x98F像大多数应用程序一样通过按进行搜索的功能。我怎样才能实现该功能?据我所知,.keyboardShortcut修饰符只能在视图上使用,Button这是相当有限的。有办法或解决方法吗?谢谢!:)

\n
struct ContentView: View {\n    @State var searchText = ""\n    private let fruits = ["apple", "banana", "plum", "grape"]\n    \n    var filteredFruits: [String] {\n        if !searchText.isEmpty {\n             return fruits.filter { $0.starts(with: searchText.lowercased()) }\n        } else {\n            return fruits\n        }\n    }\n\n    var body: some View {\n        NavigationView {\n            List {\n                ForEach(filteredFruits, id: \\.self) { fruit in\n                    Text(fruit.capitalized)\n                }\n            }\n            .navigationBarTitle("Search")\n            .searchable(text: $searchText) // Need to add key command to search (\xe2\x8c\x98F)\n        }\n    }\n}\n
Run Code Online (Sandbox Code Playgroud)\n

Geo*_*e_E 5

您可以使用SwiftUI-Introspect获取底层UISearchBar,然后创建一个由键盘快捷键触发的隐藏按钮来聚焦搜索栏。

\n

下面的示例允许您激活\xe2\x8c\x98F搜索栏。

\n

例子:

\n
struct ContentView: View {\n    @State private var searchText = ""\n    @State private var searchBar: UISearchBar?\n    private let fruits = ["apple", "banana", "plum", "grape"]\n\n    var filteredFruits: [String] {\n        if !searchText.isEmpty {\n             return fruits.filter { $0.starts(with: searchText.lowercased()) }\n        } else {\n            return fruits\n        }\n    }\n\n    var body: some View {\n        NavigationView {\n            List {\n                ForEach(filteredFruits, id: \\.self) { fruit in\n                    Text(fruit.capitalized)\n                }\n            }\n            .navigationBarTitle("Search")\n            .searchable(text: $searchText)\n            .background(\n                Button("Search fruits") {\n                    focusSearchBar()\n                }\n                .keyboardShortcut("F", modifiers: .command)\n                .hidden()\n            )\n        }\n        .introspectNavigationController { nav in\n            searchBar = nav.navigationBar.subviews.first { view in\n                view is UISearchBar\n            } as? UISearchBar\n        }\n    }\n\n    private func focusSearchBar() {\n        searchBar?.becomeFirstResponder()\n    }\n}\n
Run Code Online (Sandbox Code Playgroud)\n

结果:

\n

结果

\n

  • 问一个链接到这里的新问题被否决了。相信绝对没有办法做到这一点真是令人沮丧。我不相信这一点,我知道必须有一种方法,因为数十个苹果自己的应用程序都可以按 <kbd>⌘</kbd><kbd>F</kbd> 进行搜索。这里发生了什么? (3认同)

Den*_* L. 2

两年后,我们收到了苹果的回复。

从 iOS 17 开始,您现在可以使用.searchable(text: Binding<String>, isPresented: Binding<Bool>)

struct ContentView: View {
    @State private var searchText = ""
    @State private var isSearching = false
    private let fruits = ["apple", "banana", "plum", "grape"]
    
    var filteredFruits: [String] {
        if !searchText.isEmpty {
             return fruits.filter { $0.starts(with: searchText.lowercased()) }
        } else {
            return fruits
        }
    }

    var body: some View {
        NavigationView {
            List {
                ForEach(filteredFruits, id: \.self) { fruit in
                    Text(fruit.capitalized)
                }
            }
            .navigationBarTitle("Search")
            .searchable(text: $searchText, isPresented: $isSearching)
            .background(Button("", action: { isSearching = true }).keyboardShortcut("f").hidden()) // some means to trigger the key command
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

希望这对大家有帮助:)