#swiftui #toolbar #macos-big-sur #nssearchtoolbaritem
#swiftui #панель инструментов #macos-big-sur #nssearchtoolbaritem
Вопрос:
Я смотрел видео WWDC «Adopt the new look of macOS», где они представили NSSearchToolBarItem в Swift в 11:32 в видео.
Это именно то, что мне нужно сделать, но как мне добавить этот поиск на панель инструментов в SwiftUI?
Существует множество сложных примеров, но все они, похоже, были написаны до появления этого нового API. Должен быть более простой способ?
import SwiftUI
var listItems = ["Item 1", "Item 2", "Item 3", "Item 4"]
struct ContentView: View
{
@State var select: String? = "Item 1"
@State var searchText: String = "hello"
var body: some View
{
VStack
{
NavigationView
{
List
{
ForEach((0..<listItems.count), id: .self)
{index in
Label(listItems[index], systemImage: "briefcase")
}
}
}
.toolbar
{
Button(action: {})
{
Label("Upload", systemImage: "square.and.pencil")
}
TextField("Search", text: $searchText)
}
}
}
}
Ответ №1:
Не похоже, что существует очевидный способ сделать это NSSearchToolbarItem
напрямую, но, изучая этот класс, он использует NSSearchField
under the hood, который относительно прост в использовании в SwiftUI, используя NSViewRepresentable
:
struct SearchField: NSViewRepresentable {
class Coordinator: NSObject, NSSearchFieldDelegate {
var parent: SearchField
init(_ parent: SearchField) {
self.parent = parent
}
func controlTextDidChange(_ notification: Notification) {
guard let searchField = notification.object as? NSSearchField else {
print("Unexpected control in update notification")
return
}
self.parent.search = searchField.stringValue
}
}
@Binding var search: String
func makeNSView(context: Context) -> NSSearchField {
NSSearchField(frame: .zero)
}
func updateNSView(_ searchField: NSSearchField, context: Context) {
searchField.stringValue = search
searchField.delegate = context.coordinator
}
func makeCoordinator() -> Coordinator {
return Coordinator(self)
}
}
Затем вы можете использовать это размещенное представление непосредственно внутри ToolbarItem
:
ToolbarItem {
SearchField(search: $filter)
.frame(minWidth: 100, idealWidth: 200, maxWidth: .infinity)
}
Возможно, вы захотите немного изменить размеры (в .frame()
вызове), чтобы они соответствовали выходным собственным размерам платформы, но, похоже, это довольно точно соответствует тому, как выглядит Notes.app.
Элемент панели инструментов поиска в Notes.app:
Элемент панели инструментов поиска из приведенного выше примера кода: