[英]How to show/hide the progressHUD, with MVVM and RxSwift in swift
I'm beginning with MVVM in order to well separate logic code from the view. 我从MVVM开始,以便将逻辑代码从视图中分离出来。 But I have some concern about where to put the progressHUD related code when tapping a button that makes a request. 但我有点担心在点击发出请求的按钮时将progressHUD相关代码放在哪里。
Before, I used to do that: 之前,我曾经这样做过:
//Before
@IBAction func startRequestTapped() {
SVProgressHUD.show()
self.apiClient.requestObservable().subscribe(onError: { (error) in
SVProgressHUD.hide()
}, onCompleted: {
SVProgressHUD.hide()
})
}
But when I use mvvm, I do like that: 但是当我使用mvvm时,我确实喜欢这样:
//In the viewModel
public var validateButtonDidTap = PublishSubject<Void>()
init() {
validateButtonDidTap.flatMap { (_)
return self.apiClient.requestObservable()
}
}
// In the viewController
viewDidLoad() {
let tap = self.validateButton.rx.tap
tap.bindTo(self.viewModel.validateButtonDidTap)
}
And amongst that, I don't know where to put the the ProgressHUD hide or show. 其中,我不知道将ProgressHUD隐藏或显示放在哪里。
Mark answer is right, but I am going to guide you step by step. 马克答案是对的,但我会一步一步地指导你。
Let's supose you're going to try signing in. 让我们打算你试着登录。
Copy ActivityIndicator.swift file in your project. 复制项目中的ActivityIndicator.swift文件 。
In the viewModel
: 在viewModel
:
//MARK: - Properties /// The http client private let apiClient: YourApiClient /// Clousure when button is tapped var didTappedButton: () -> Void = {} /// The user var user: Observable<User> /// Is signing process in progress let signingIn: Observable<Bool> = ActivityIndicator().asObservable() //MARK: - Initialization init(client: YourApiClient) { self.client = client self.didTappedButton = { [weak self] in self.user = self.apiClient .yourSignInRequest() .trackActivity(self.signingIn) .observeOn(MainScheduler.instance) } }
Create an extension of SVProgressHUD: (I don't know SVProgressHUD library, but it would be something like this. Please fix it if needed) 创建SVProgressHUD的扩展:(我不知道SVProgressHUD库,但它会是这样的。请在需要时修复它)
extension Reactive where Base: SVProgressHUD { /// Bindable sink for `show()`, `hide()` methods. public static var isAnimating: UIBindingObserver<Base, Bool> { return UIBindingObserver(UIElement: self.base) { progressHUD, isVisible in if isVisible { progressHUD.show() // or other show methods } else { progressHUD.dismiss() // or other hide methods } } } }
In your viewController
: 在你的viewController
:
@IBAction func startRequestTapped() { viewModel.didTappedButton() } override func viewDidLoad() { // ... viewModel.signingIn .bindTo(SVProgressHUD.rx.isAnimating) .addDisposableTo(disposeBag) }
Accepted answer updated to Swift 4, RxSwift 4.0.0 and SVProgressHUD 2.2.2: 接受的答案更新为Swift 4,RxSwift 4.0.0和SVProgressHUD 2.2.2:
3- Extension: 3-扩展:
extension Reactive where Base: SVProgressHUD {
public static var isAnimating: Binder<Bool> {
return Binder(UIApplication.shared) {progressHUD, isVisible in
if isVisible {
SVProgressHUD.show()
} else {
SVProgressHUD.dismiss()
}
}
}
}
4- Controller: 4-控制器:
viewModel.signingIn.asObservable().bind(to: SVProgressHUD.rx.isAnimating).disposed(by: disposeBag)
You could try using an ActivityIndicator
. 您可以尝试使用ActivityIndicator
。
See the example here: https://github.com/RxSwiftCommunity/RxSwiftUtilities 请参阅此处的示例: https : //github.com/RxSwiftCommunity/RxSwiftUtilities
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.