SwiftUI 原生 SearchBar:搜索文本更改时触发 API 请求

问题描述 投票:0回答:1

2020年我第一次接触SwiftUI的时候,SearchBar需要回滚到UIKit,因为当时SwiftUI对它的支持还不是很好。

我使用下面的代码在 2020 年创建搜索栏

import SwiftUI

struct SearchBar: UIViewRepresentable {
    
    @Binding var text: String
    var onTextChanged: (String) -> Void
    
    class Coordinator: NSObject, UISearchBarDelegate {
        
        @Binding var text: String
        var onTextChanged: (String) -> Void
        
        init(text: Binding<String>, onTextChanged: @escaping (String) -> Void) {
            _text = text
            self.onTextChanged = onTextChanged
        }
        
        // Show cancel button when the user begins editing the search text
        func searchBarTextDidBeginEditing(_ searchBar: UISearchBar) {
            searchBar.showsCancelButton = true
        }
        
        func searchBar(_ searchBar: UISearchBar, textDidChange searchText: String) {
            text = searchText
            onTextChanged(text)
        }
        
        func searchBarCancelButtonClicked(_ searchBar: UISearchBar) {
            text = ""
            searchBar.showsCancelButton = false
            searchBar.endEditing(true)
            // Send back empty string text to search view
            onTextChanged(text)
        }
    }

我创建如下代码。只是想知道我们现在是否可以使用纯 SwiftUI 本地完成它。如何在每次搜索文本更改时触发 API 请求?

struct MainScreenView: View {
    @StateObject var subListViewModel = SubListViewModel()
    @State private var searchText = ""
    @State private var page = 1
    
    var body: some View {
        TabView {
            NavigationStack {
                List {
                    ForEach(subListViewModel.searchResults, id: \.self) { sub in
                        Text(sub.title)
                        Text(sub.language)
                        Text(sub.year)
                        Text(sub.imgUrl)
                    }
                }
                .navigationTitle("Search")
                .onAppear() {
                    // Pagenated
                }
            }
            .searchable(text: $searchText, prompt: "Enter movie / tv series name") {
//                ForEach(subListViewModel.searchResults, id: \.self) { result in
//                    Text("Are you looking for \(result.title)?").searchCompletion(result.title)
//                }
            }
            .tabItem {
                Image(systemName: "magnifyingglass")
                Text("Search")
            }
            
            // MARK: 2nd tab
            Text("TBD")
                .tabItem {
                    Image(systemName: "gear")
                    Text("Settings")
                }
        }
    }
}
swiftui searchbar
1个回答
0
投票

这是我用 SwiftUI 编写的自定义解决方案。可搜索不符合我的某些要求。 将您的输入绑定在那里。另外,如果你想进行 api 调用: 添加绑定模型属性, 添加 onChange 观察者。

 struct SearchBarView: View {
            
            @Binding var input: String
            @Binding var yourModel: Model
                
            var body: some View {
                HStack(spacing: .zero) {
                    HStack(spacing: .zero) {
                        Image(systemName: "magnifyingglass")
                            .padding(5)
                        
                        TextField("Search Fighters", text: $input)
                        .onChange(of: input) { newValue in
                           Task {
                              let response = await makeApiCall(query: newValue)
                              yourModel = response
                           }
                        }
                    }
                    .background(.white)
                    .cornerRadius(20)
                    
                    Spacer()
                    
                    if !input.isEmpty {
                        Button("Cancel") {
                            withAnimation {
                                input = ""
                            }
                        }
                        .tint(.black)
                        .font(.body)
                        .padding(.leading, 10)
                    }
                }
                .padding(15)
                .background(Color.init(white: 0.9))
            }
        }

然后在父视图中添加SearchBarView并绑定所有必要的属性。

© www.soinside.com 2019 - 2024. All rights reserved.