隐藏键盘后,我想启用一个按钮。如何使用rxSwift执行此操作?我尝试了这段代码,但从未调用过闭包:
NotificationCenter.default.rx.notification(UIResponder.keyboardWillHideNotification)
.map { _ in if let cancelButton = self.searchBar.value(forKey: "cancelButton") as? UIButton {
cancelButton.isEnabled = true
} }
可观察对象除非订阅,否则不会做任何事情。由于您未使用subscribe
(或bind
,即当发现错误时会断言的subscribe
),因此观察者没有执行任何操作。有点像创建对象,但从不调用其任何功能。
我会这样写:
let cancelButton = searchBar.value(forKey: "cancelButton") as! UIButton
NotificationCenter.default.rx.notification(UIResponder.keyboardWillHideNotification)
.map { _ in true }
.take(1)
.subscribe(cancelButton.rx.isEnabled)
.disposed(by: disposeBag)
Daniel的答案是正确的,可能是最简单的方法,但这是另一个使用RxCocoa进行相同操作的示例:
let keyboardShown = NotificationCenter.default.rx.notification(UIResponder.keyboardWillShowNotification)
let keyboardHidden = NotificationCenter.default.rx.notification(UIResponder.keyboardWillHideNotification)
let isCancelEnabled = Observable.merge(keyboardShown.map { _ in false }, keyboardHidden.map { _ in true })
.startWith(false)
.asDriver(onErrorJustReturn: false)
let cancelButton = searchBar.value(forKey: "cancelButton") as! UIButton
isCancelEnabled
.drive(cancelButton.rx.isEnabled)
.disposed(by: disposeBag)
这可能是一个稍长的版本,但是现在使用MVVM模式非常简单,在ViewModel中声明isCancelEnabled,在ViewController中取消cancelDrive的驱动。
P.S。我认为您不希望像Daniel所建议的那样包含.take(1),因为它在第一个事件中可以正常工作,但随后该订阅将被处置,并且将不再起作用。