SwiftUI:如何在macOS 11上使用NSSearchToolBarItem?

4

我观看了 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)
            }
        }
    }
}
1个回答

13

直接使用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 中的搜索工具栏项:

显示Notes.app中搜索工具栏项的截图

来自上面示例代码的搜索工具栏项:

显示示例代码中搜索工具栏的截图


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接