【发布时间】:2018-09-07 09:03:12
【问题描述】:
我实现了一个“反应式”UIAlertController,所以我可以得到一个按下按钮的Observable<Int>。 (见下面的代码)。
我的一个或多个问题是:
- 这个实现是否正确?我不喜欢存储观察者;我想知道是否有更好的解决方案。
- 或者...是否已经在 ReactiveCocoa 或 RxSwift 中实现了此功能?
这里是实现。我删除了与问题无关的部分。
class AlertBuilder {
typealias AlertAction = (Int) -> ()
private let alert: UIAlertController
/** If observable() is called, we keep here the observers to notify them */
private var observers: [AnyObserver<Int>] = []
init(alert: UIAlertController) {
self.alert = alert
}
/** When using observable(), the action is not needed. */
func button(_ title: String, style: UIAlertActionStyle = .default, action: AlertAction? = nil) -> AlertBuilder {
let buttonIndex = alert.actions.count
alert.addAction( UIAlertAction(title: title, style: style, handler: { [weak self] _ in
// Callback via action
action?(buttonIndex)
// Callback via observers
if let this = self {
for observer in this.observers {
observer.onNext(buttonIndex)
observer.onCompleted()
}
this.observers = []
}
}) )
return self
}
/**
* Returns an Observable that will emit the pressed button index and complete.
* It's important to keep a reference to the AlertBuilder, otherwise the events won't be received.
*/
func observable() -> Observable<Int> {
return Observable<Int>.create { observer in
self.observers.append(observer)
return Disposables.create()
}
}
}
您可以从控制器中使用它,如下所示:
let alert = UIAlertController(title: "title", message: "msg", preferredStyle: .actionSheet)
let builder = AlertBuilder(alert: alert)
.button("no", style: .destructive)
.button("yes")
self.present(alert, animated: true, completion: nil)
self.builder.observable()
.subscribe(onNext: { buttonIndex in /* ... */ })
.disposed(by: bag)
// keep reference to builder so observable() works
self.builder = builder
【问题讨论】:
标签: ios reactive-cocoa rx-swift