RxSwift - 以编程方式在UISearchBar中触发搜索

时间:2017-11-19 22:55:49

标签: ios swift rx-swift rx-cocoa

我正在观察UISearchBar.rx.text属性,以便在用户键入某些文本时执行一些与搜索相关的操作。 但在某些时候,我还想以编程方式触发此搜索Action。例如,在创建视图时,就像在这个例子中一样,遗憾的是,不会打印“搜索[...]”文本。

import UIKit
import RxSwift
import RxCocoa

class ViewController: UIViewController {
  @IBOutlet weak var mySearchBar: UISearchBar!

  let disposeBag = DisposeBag()

  override func viewDidLoad() {
    super.viewDidLoad()
    // Trigger search when text changes
    mySearchBar.rx.text.subscribe(onNext: { (text)
         print("Searching for \(text)...")
         // do some search Action
    }
    .disposed(by: disposeBag)

    // Programmatically trigger a search
    mySearchBar.text = "Some text to search"
  }

}

问题是改变mySearchBar.text不会触发新的rx.text事件。有没有办法这样做?

例如,我知道感谢this post使用UITextField,可以使用UITextField.sendActions(for:.ValueChanged)函数。是否有类似的方法与UISearchBar这样做?

3 个答案:

答案 0 :(得分:2)

您可以使用Variable<String?>作为搜索栏更新的接收器。这样你也可以以编程方式设置它的值,并直接使用变量而不是搜索栏来推动你的行动:

class ViewController: UIViewController {
    let searchText = Variable<String?>(nil)
    let searchBar = UISearchBar()
    let disposeBag = DisposeBag()

    override func viewDidLoad() {
        super.viewDidLoad()
        searchBar.rx.text.asDriver()
            .drive(searchText)
            .disposed(by: disposeBag)

        searchText.asObservable().subscribe(onNext: { [weak self] (text) in
            if let welf = self, welf.searchBar.text != text {
                welf.searchBar.text = text
            }
        })
            .disposed(by: disposeBag)

        searchText.value = "variables so cool"
        searchText.asObservable().subscribe(onNext: { [weak self] (text) in
            self?.doStuff(text)
        })
        .disposed(by: disposeBag)
    }
}

答案 1 :(得分:1)

UITextBar也适用。

以编程方式设置.text 不会自动触发操作,我不知道为什么!但是UITextField也是如此。

每次更新sendActions子类的.text属性后,调用UIView

尝试一下:

// Programmatically trigger a search
    mySearchBar.text = "Some text to search"    
    mySearchBar.sendActions(for: .valueChanged)

答案 2 :(得分:0)

这是Driver s的简单用法

import UIKit
import RxCocoa
import RxSwift
class SearchViewController: UIViewController {

    @IBOutlet weak var searchBar: UISearchBar!
    let disposeBag = DisposeBag()
    override func viewDidLoad() {
        super.viewDidLoad()
        let dataModels = Driver.just(["David", "Behrad","Tony","Carl","Davidov"])
        let searchingTextDriver = searchBar.rx.text.orEmpty.asDriver()
        let matchedCases = searchingTextDriver.withLatestFrom(dataModels){ searchingItem,models in
            return models.filter({ (item) -> Bool in
                 return item.contains(searchingItem)
            })
        }
        matchedCases.do(onNext: { (items) in
            print(items)            
        }).drive().disposed(by: disposeBag)
    }
}

如您所见,我们创建了一个dataModels驱动程序,它可能是您的网络或数据库获取的响应。 搜索文本转换为驱动程序,然后与dataModels混合以创建matchedCases