i try to filter data from my table View. When i select one value from picker View, The data suppose to filter based on the category and the table view should reload with filtered data. here i attach the code
struct RecipeList {
let id: Int
let catid: String
let name: String
let description: String
let ingredient: String
let step: String
let image: String
let img: NSData
//static var dataSource = BehaviorRelay(value: [RecipeList]())
static var items = [RecipeList]()
}
here how i fetch data to table View
func setupCellConfiguration() {
let recipeList = Observable.just(RecipeList.items)
recipeList
.bind(to: tableView
.rx
.items(cellIdentifier: RecipeListCell.Identifier,
cellType: RecipeListCell.self)) { row, recipe, cell in
cell.configureWithRecipe(recipe: recipe)
}
.disposed(by: disposeBag)
}
Here how pick event on picker view
func setupRecipeTypePickerView(textField: UITextField) {
let pickerView = UIPickerView()
pickerView.selectRow(Int(self.selectedRecipeType) ?? 0, inComponent: 0, animated: false)
textField.inputView = pickerView
let recipeType = Observable.of(RecipeType.items)
recipeType.bind(to: pickerView.rx.itemTitles) { (row, element) in
return "\(element.name)"
}
.disposed(by: disposeBag)
pickerView.rx.itemSelected
.subscribe { (event) in
switch event {
case .next(let selected):
selected.row == 0 ? (self.isFilter = false) : (self.isFilter = true)
let recipeType = RecipeType.items[selected.row]
textField.text = recipeType.name
self.selectedRecipeType = recipeType.id
RecipeList.items.append(contentsOf: RecipeList.items.filter({$0.catid == recipeType.id}))
default:
break
}
}
.disposed(by: disposeBag)
}
Here how append data from Core data to Model
func getRecipeList() {
RecipeList.items.removeAll()
guard let appDelegate = UIApplication.shared.delegate as? AppDelegate else { return }
let managedContext = appDelegate.persistentContainer.viewContext
let fetchRequest = NSFetchRequest<NSFetchRequestResult>(entityName: Common.ENTITYNAME)
do {
let result = try managedContext.fetch(fetchRequest)
for data in result as! [NSManagedObject] {
let id = data.value(forKey: "id") as! Int
let catid = data.value(forKey: "catid") as? String ?? "1"
let name = data.value(forKey: "name") as! String
let description = data.value(forKey: "rdescription") as! String
let ingredient = data.value(forKey: "ingredient") as! String
let step = data.value(forKey: "step") as! String
let image = data.value(forKey: "image") as! String
let img = data.value(forKey: "img") as! NSData
let recipe = RecipeList(id: id, catid: catid, name: name, description: description, ingredient: ingredient, step: step, image: image, img: img)
RecipeList.items.append(recipe)
}
// RecipeList.dataSource.accept(RecipeList.items)
} catch {
print("Failed")
}
}
I try alot solution from multiple sources, seems does not work. This is my first day learning RXSwift. Usually i didnt use RXSwift, i just simply, create variable for filtered data, then rereload the tableView
The missing bit in your code is that you are just
emitting the RecipeList.items
and then completing. You have to emit a new value from recipeList
every time you want the table view to reload.
Try something like this instead:
class Example: UIViewController {
var tableView: UITableView!
var textField: UITextField!
let disposeBag = DisposeBag()
override func viewDidLoad() {
super.viewDidLoad()
let pickerView = createPickerView()
textField.inputView = pickerView
configureTextField(pickerView: pickerView)
configureTableView(pickerView: pickerView)
}
func createPickerView() -> UIPickerView {
let pickerView = UIPickerView()
Observable.just(RecipeType.items)
.bind(to: pickerView.rx.itemTitles) { row, element in
return element.name
}
.disposed(by: disposeBag)
return pickerView
}
func configureTextField(pickerView: UIPickerView) {
pickerView.rx.itemSelected
.map { RecipeType.items[$0.row].name }
.bind(to: textField.rx.text)
.disposed(by: disposeBag)
}
func configureTableView(pickerView: UIPickerView) {
let recipeList = Observable.just(RecipeList.items)
Observable.combineLatest(recipeList, pickerView.rx.itemSelected.map { $0.row })
.map { (list, selected) -> [RecipeList] in
guard selected != 0 else { return list }
let recipeType = RecipeType.items[selected]
return list.filter { $0.catid == recipeType.id }
}
.bind(to: tableView.rx.items(cellIdentifier: RecipeListCell.Identifier,
cellType: RecipeListCell.self)) { row, recipe, cell in
cell.configureWithRecipe(recipe: recipe)
}
.disposed(by: disposeBag)
}
}