ios - 如何在 swift 中使用 MVVM 和 RxSwift 显示/隐藏 progressHUD

标签 ios swift mvvm rx-swift svprogresshud

我从 MVVM 开始,以便很好地将逻辑代码与 View 分开。但是我担心在点击发出请求的按钮时将 progressHUD 相关代码放在哪里。

以前,我曾经这样做过:

//Before 
@IBAction func startRequestTapped() {
   SVProgressHUD.show()
    self.apiClient.requestObservable().subscribe(onError: { (error) in
        SVProgressHUD.hide()                    
    }, onCompleted: { 
        SVProgressHUD.hide()                                        
    })
}

但是当我使用 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)
}

其中,我不知道将 ProgressHUD 隐藏或显示在哪里。

最佳答案

标记答案是正确的,但我将逐步指导您。

假设您要尝试登录。

  1. 复制 ActivityIndicator.swift file在你的项目中。

  2. 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. 创建 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. 在您的viewController中:

    @IBAction func startRequestTapped() {
        viewModel.didTappedButton()
    }
    
    override func viewDidLoad() {
    
        // ...
    
        viewModel.signingIn
                 .bindTo(SVProgressHUD.rx.isAnimating)
                 .addDisposableTo(disposeBag)
    }
    

关于ios - 如何在 swift 中使用 MVVM 和 RxSwift 显示/隐藏 progressHUD,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41932734/

相关文章:

ios - 背景 gif 位置转换到其他 ViewController

ios - 视障用户无需点击屏幕即可进行语音输入

swift - 如果使用从右到左的语言,String.prefix() 是否像 String.suffix 一样工作?

javascript - 当包含异步请求时自动渲染 react 一次

wpf - 将数据集转换为可观察集合

java - 有api调用时如何在不重复代码的情况下膨胀progressBar布局

ios - 取消链接 AWS 链接登录的问题(例如 Facebook)

ios - 无法转换类型 'NSString' 的值?预期参数类型 'String'

ios - 获取 Laravel JSON feed 中帖子的页码

python - 在 python 中验证 StoreKit 2 事务 jwsRepresentation 的正确方法是什么?