Reputation: 391
There is a solution for iOS 17 onwards now
One of the new features introduced in iOS 15 SwiftUI 3.0 was the .searchable
view modifier. Here is a simple example of how it works below. I would like to add the ability to search by pressing ⌘F
as most apps have. How can I implement that functionality? As far as I am aware the .keyboardShortcut
modifier can only be used on Button
views which is quite limiting. Is there a way or workaround? Thanks! :)
struct ContentView: View {
@State var searchText = ""
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) // Need to add key command to search (⌘F)
}
}
}
Upvotes: 15
Views: 3135
Reputation: 391
Here I am, 2 years later and we have a response from Apple.
As of iOS 17 you can now use .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
}
}
}
Hope this helps you all :)
Upvotes: 9
Reputation: 30391
You can use SwiftUI-Introspect to get the underlying UISearchBar
, and then create a hidden button triggered by the keyboard shortcut to focus the search bar.
The example below allows you to do ⌘F to activate the search bar.
Example:
struct ContentView: View {
@State private var searchText = ""
@State private var searchBar: UISearchBar?
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)
.background(
Button("Search fruits") {
focusSearchBar()
}
.keyboardShortcut("F", modifiers: .command)
.hidden()
)
}
.introspectNavigationController { nav in
searchBar = nav.navigationBar.subviews.first { view in
view is UISearchBar
} as? UISearchBar
}
}
private func focusSearchBar() {
searchBar?.becomeFirstResponder()
}
}
Result:
Upvotes: 6