我正在观察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这样做?
答案 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
。