问题描述
我观看了WWDC视频“采用macOS的新外观”,他们在视频中11:32在Swift中引入了NSSearchToolBarItem。
这正是我需要做的,但是如何将搜索添加到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)
}
}
}
}
解决方法
似乎没有一种直接使用NSSearchToolbarItem
的明显方法,但是在该类中,它是在内部使用NSSearchField
,在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中的搜索工具栏项:
从上面的示例代码中搜索工具栏项: