0

由于 tvOS 14.x 中没有本机搜索栏,我必须将控件包装在 UIViewControllerRepresentable 中。只要我在模拟器上测试时使用 Mac 键盘,控件就会显示甚至返回搜索结果。我的问题是屏幕键盘永远不会获得焦点。

有什么建议么?

在此处输入图像描述

这是 UIViewControllerRepresentable 实现。

struct ScreenerSearchBar: UIViewControllerRepresentable {
@Binding var text: String
@EnvironmentObject var searchResults : Search

typealias UIViewControllerType = UISearchContainerViewController

typealias Context = UIViewControllerRepresentableContext<ScreenerSearchBar>

func makeUIViewController(context: Context) -> UIViewControllerType {
    let controller = UISearchController(searchResultsController: context.coordinator)
    controller.searchResultsUpdater = context.coordinator
    controller.searchBar.placeholder = "Search"
    controller.searchBar.tintColor = .white
    controller.inputView?.tintColor = .white
    controller.searchBar.barTintColor = .white
    controller.searchBar.searchBarStyle = .minimal
    controller.searchBar.keyboardAppearance = .dark

    return UISearchContainerViewController(searchController: controller)
}

func updateUIViewController(_ uiViewController: UIViewControllerType, context: Context) {
}

func makeCoordinator() -> ScreenerSearchBar.Coordinator {
    return Coordinator(text: $text, searchResults: searchResults)
}

//=======================================================================
class Coordinator: UIViewController, UISearchResultsUpdating {
    @Binding var text: String
    var searchResults : Search

    init(text: Binding<String>, searchResults: Search) {
        _text = text
        self.searchResults = searchResults
        super.init(nibName: nil, bundle: nil)
    }
    
    required init?(coder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
    
    func updateSearchResults(for searchController: UISearchController) {
        guard let searchText = searchController.searchBar.text else { return }
        text = searchText
        searchResults.search(for: text)
    }
}
//=======================================================================

}

在我看来,这是我使用它的方式:

struct SearchView: View {
@EnvironmentObject var searchResults : Search
@State private var keyword = ""

let columns = [
        GridItem(.fixed(400)),
        GridItem(.fixed(400)),
        GridItem(.fixed(400)),
        GridItem(.fixed(400))
    ]

var body: some View {
    VStack {
        ScreenerSearchBar(text: $keyword)
            .focusable()
        
        HStack {
            if !keyword.isEmpty {
                Text("Search results for: \"\(keyword)\"")
                    .font(.caption)
                Spacer()
            }
        }
        .padding(.top, -150)
        .focusable()
        
        ScrollView(.vertical) {
            LazyVGrid(columns: columns) {
                ForEach(searchResults.screeners, id: \.id) { screener in
                    NavigationLink(destination: TitleDetailView(screener: screener, titleDetails: TitleDetails(), hierarchy: Hierarchy())) {
                        ScreenerView(screener: screener, categoryId: -99, origin: .search)
                            .focusable()
                    }
                    .buttonStyle(PlainNavigationLinkButtonStyle())
                }
            } //vgrid
            .focusable()
            .padding(.top, -100)
            
        } // scrollview
    } // vstack
}

}

4

0 回答 0