RxSwift - 从 UIPickerView 的表视图中过滤数据
RxSwift - Filter data from tableview from UIPickerView
我尝试从我的 table 视图中过滤数据。当我 select 来自选择器视图的一个值时,数据应该根据类别进行过滤,并且 table 视图应该重新加载过滤后的数据。
我附上代码
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]()
}
这里是我如何获取数据到 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)
}
这里是如何在选择器视图中选择事件
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({[=12=].catid == recipeType.id}))
default:
break
}
}
.disposed(by: disposeBag)
}
这里是如何将数据从核心数据附加到模型
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")
}
}
我尝试了很多来自多个来源的解决方案,似乎不起作用。这是我学习 RXSwift 的第一天。通常我不使用 RXSwift,我只是简单地为过滤后的数据创建变量,然后重新加载 tableView
您的代码中缺少的一点是您 just
发出 RecipeList.items
然后完成。每次要重新加载 table 视图时,都必须从 recipeList
发出一个新值。
试试这样的方法:
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[[=10=].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 { [=10=].row })
.map { (list, selected) -> [RecipeList] in
guard selected != 0 else { return list }
let recipeType = RecipeType.items[selected]
return list.filter { [=10=].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)
}
}
我尝试从我的 table 视图中过滤数据。当我 select 来自选择器视图的一个值时,数据应该根据类别进行过滤,并且 table 视图应该重新加载过滤后的数据。 我附上代码
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]()
}
这里是我如何获取数据到 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)
}
这里是如何在选择器视图中选择事件
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({[=12=].catid == recipeType.id}))
default:
break
}
}
.disposed(by: disposeBag)
}
这里是如何将数据从核心数据附加到模型
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")
}
}
我尝试了很多来自多个来源的解决方案,似乎不起作用。这是我学习 RXSwift 的第一天。通常我不使用 RXSwift,我只是简单地为过滤后的数据创建变量,然后重新加载 tableView
您的代码中缺少的一点是您 just
发出 RecipeList.items
然后完成。每次要重新加载 table 视图时,都必须从 recipeList
发出一个新值。
试试这样的方法:
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[[=10=].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 { [=10=].row })
.map { (list, selected) -> [RecipeList] in
guard selected != 0 else { return list }
let recipeType = RecipeType.items[selected]
return list.filter { [=10=].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)
}
}