如何使用 RxSwift 将 UISearchBar 绑定到 UITableView

问题描述

我有一组数字,我希望 tableview 显示我在搜索栏中输入的数字。这是我的代码,我不知道在(而不是).subscribe

之后的行中该写什么
let dataSource = BehaviorRelay(value: [String]())
let disposeBag = disposeBag()
var numbers = ["1","2","3","4","5"]

override func viewDidLoad() {
    super.viewDidLoad()
    
    dataSource.accept(numbers)
    
    searchBar.rx.text.orEmpty
        .throttle(.milliseconds(2000),scheduler: MainScheduler.instance)
        .filter{self.numbers.contains($0)}
        .subscribe(onNext: 
            
        })
    self.dataSource
        .asObservable()
        .bind(to: tableView.rx.items(cellIdentifier: "Cell",cellType: TableViewCell.self)) {(row,element,cell) in
            cell.textLabel?.text = element
        }
        .disposed(by: disposeBag)

可能是其他原因不行,还是谢谢大家的帮助

解决方法

更新:

您想将反应式代码视为因果链。一些副作用发生会导致一些其他副作用。当然,因果之间有业务逻辑。

首先请注意,不需要主题。在Intro To Rx一书中,我们了解到:

Subjects 提供了一种方便的方式来浏览 Rx,但不建议在日常使用中使用它们。

既然我们正在考虑“因果关系”……我们想要达到的效果是什么?这将是表格视图的输出:

  • 每当用户点击添加按钮时添加一个数字,
  • 每当用户点击删除按钮时删除最后一个数字,
  • 并在用户在文本中输入数字时过滤列表 领域...

这是三个原因以及定义原因如何影响结果的逻辑。

final class Example: UIViewController {
    var searchBar: UISearchBar!
    var addButton: UIButton!
    var deleteButton: UIButton!
    var tableView: UITableView!
    let disposeBag = DisposeBag()

    override func viewDidLoad() {
        super.viewDidLoad()

        enum Input {
            case add
            case delete
        }

        let initial = ["1","2","3","4","5"] // this is what we start with
        Observable.merge(
            addButton.rx.tap.map { Input.add },// flag addButton taps for adding a number
            deleteButton.rx.tap.map { Input.delete } // flag deleteButton taps for deleting a number
        )
        .scan(into: initial) { state,input in // setup a state machine that:
            switch input {
            case .add:
                state.append("\(state.count + 1)") // adds a number when the add event happens
            case .delete:
                state.removeLast() // removes the last number when a delete event happens
            }
        }
        .withLatestFrom(searchBar.rx.text) { list,text in
            list.filter { $0 == text } // here we filter the list based on the value in the search bar
        }
        .startWith(initial) // show the initial values at start
        .bind(to: tableView.rx.items(cellIdentifier: "Cell",cellType: UITableViewCell.self)) { _,element,cell in
            cell.textLabel?.text = element
        }
        .disposed(by: disposeBag)
    }
}

您可能想让过滤器比我上面的更复杂或更简单。为了使上述可测试,只需将闭包移到单独的函数中,以便它们可以独立测试。