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

Posted

技术标签:

【中文标题】SwiftUI:如何在 macOS 11 上使用 NSSearchToolBarItem?【英文标题】:SwiftUI: How to use NSSearchToolBarItem on macOS 11? 【发布时间】:2020-10-15 17:36:41 【问题描述】:

我观看了 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】:

似乎没有一种明显的方法可以直接使用NSSearchToolbarItem 来执行此操作,但是查看该类,它在引擎盖下使用了NSSearchField,这在使用NSViewRepresentable 的SwiftUI 中相对容易使用:

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 中搜索工具栏项:

从上面的示例代码中搜索工具栏项:

【讨论】:

以上是关于SwiftUI:如何在 macOS 11 上使用 NSSearchToolBarItem?的主要内容,如果未能解决你的问题,请参考以下文章

(SwiftUI, MacOS 11.0) 如何在 SecureTextFeild 中检测焦点?

SwiftUI:如何在 macOS 应用程序中实现编辑菜单

如何使用 SwiftUI 在 macOS 上可靠地检索窗口的背景颜色?

如何在 macOS 上检测 SwiftUI 中的键盘事件?

如何在 macOS 上检测 SwiftUI 中的键盘事件?

在 MacOS 上构建 SwiftUI “Hello World”