简体   繁体   English

如何使用MVVM和RxSwift快速显示/隐藏progressHUD

[英]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. 让我们打算你试着登录。

  1. Copy ActivityIndicator.swift file in your project. 复制项目中的ActivityIndi​​cator.swift文件

  2. 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) } } 
  3. 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 } } } } 
  4. 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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM