swift 使用合并快速过滤数据到搜索栏

ar5n3qh5  于 2023-03-17  发布在  Swift
关注(0)|答案(1)|浏览(148)

我试图返回搜索结果时,用户类型到搜索栏。在这里,我使用合并方法与Swift用户界面。我试图绑定的对象形式视图模型的变化功能,但我得到以下错误。

无法将类型“Published.Publisher”的值转换为预期的参数类型“(String)-〉Void”

下面是我的viewModel代码。

final class FruitListViewModel: FruitListViewModelType, ObservableObject {
        
        private let service: Service!
        @Published private(set) var fruits = [Fruits]()
        // @Published var filteredFruit: [Fruits] = []
        private var cancellable = Set<AnyCancellable>()
        @Published var searchText: String = ""
        
        
        init(service:Service = ServiceImpl()) {
            self.service = service
            
        }
        
        func fetchFruit() {
            let client = ServiceClient(baseUrl:EndPoints.baseUrl.rawValue, path:Path.fruitList.rawValue, params:"", method:"get")
            
            service.fetchData(client: client, type: [Fruits].self)
                .receive(on: RunLoop.main)
                .sink { completion in
                    switch completion {
                    case let .failure(error):
                        print(error)
                    default:
                        break
                    }
                } receiveValue: { response in
                    self.fruits = response
                }.store(in: &cancellable)
            
            $searchText
                .combineLatest($fruits)
                .debounce(for: .milliseconds(80), scheduler: RunLoop.main)
                .map { (searchText, fruit) -> [Fruits]  in
                    guard !searchText.isEmpty else {
                        return fruit
                    }
                    let lowercasedText = searchText.lowercased()
                    let filterFruitList = fruit.filter { (fruit) -> Bool in
                        fruit.name.lowercased().contains(lowercasedText) ||
                        fruit.genus.lowercased().contains(lowercasedText) ||
                        fruit.family.lowercased().contains(lowercasedText)
                    }
                    return filterFruitList
                }
                .sink { [weak self] (filterList) in
                    self?.fruits = filterList
                }
                .store(in: &cancellable)
        }

}

下面是进入视图的代码。

struct ContentView: View {

    @EnvironmentObject private var viewModel: FruitListViewModel
    @State var searchText = ""

    var body: some View {
        NavigationView {
            List {
                ForEach(viewModel.fruits) { fruit in
                    NavigationLink(destination: FruitDetailsView(fruit: fruit)) {
                        RowView(name: fruit.name, genus: fruit.genus, family: fruit.family)
                    }
                }
            }
            .searchable(text: $viewModel.searchText)
            .onChange(of: viewModel.searchText, perform: viewModel.$searchText)
            .task {
                viewModel.fetchFruit()
            }
            .navigationTitle("Fruits List")
        }
        .onAppear {

            viewModel.fetchFruit()
        }
    }

}

下面是错误的屏幕截图。

搜索筛选结果。

gab6jxml

gab6jxml1#

替换

@Published private(set) var fruits = [Fruits]()
// @Published var filteredFruit: [Fruits] = []

@Published private(set) var fruits = [Fruits]()
@Published var filteredFruit: [Fruits] = []

替换

.sink { [weak self] (filterList) in
    self?.fruits = filterList
}

.sink { [weak self] (filterList) in
    self?.filteredFruit = filterList
}

替换

struct ContentView: View {

    @EnvironmentObject private var viewModel: FruitListViewModel
    @State var searchText = ""
   
    var body: some View {
        NavigationView {
            List {
                ForEach(viewModel.fruits) { fruit in
                    NavigationLink(destination: FruitDetailsView(fruit: fruit)) {
                        RowView(name: fruit.name, genus: fruit.genus, family: fruit.family)
                    }
                }
            }
            .searchable(text: $viewModel.searchText)
            .onChange(of: viewModel.searchText, perform: viewModel.$searchText)
            .task {
                viewModel.fetchFruit()
            }
            .navigationTitle("Fruits List")
        }
        .onAppear {

            viewModel.fetchFruit()
        }
    }

}

struct ContentView: View {

    @EnvironmentObject private var viewModel: FruitListViewModel

    var body: some View {
        NavigationView {
            List {
                ForEach(viewModel.filteredFruit) { fruit in
                    NavigationLink(destination: FruitDetailsView(fruit: fruit)) {
                        RowView(name: fruit.name, genus: fruit.genus, family: fruit.family)
                    }
                }
            }
            .searchable(text: $viewModel.searchText)
            .navigationTitle("Fruits List")
        }
        .onAppear {
            viewModel.fetchFruit()
        }
    }

}

和(不相关)声明

private let service: Service // no exclamation mark

旁注:
请合并fruit(s)的拼写,英语中没有后缀为s的复数形式,并且模型结构应该命名为Fruit

相关问题