【问题标题】:RxSwift Tap Event not triggeredRxSwift Tap 事件未触发
【发布时间】:2018-12-18 16:03:12
【问题描述】:

我正在使用 RxSwif 实现 mvvm。

会发生什么:

  • 验证字段(在两个文本字段中写入 7 个字符)。
  • 点击登录按钮。
  • 调用 API 没问题。
  • 再次点击按钮。
  • API 未被调用。

我注意到每次我在 textFields 中写一些东西时“validObservable”都会发生变化,这很好。

视图控制器:

    var viewModel: LoginViewModelType!
  let disposeBag = DisposeBag()
  @IBOutlet weak var dniTextField: UITextField!
  @IBOutlet weak var passwordTextField: UITextField!
  @IBOutlet weak var logInButton: UIButton!

  override func viewDidLoad() {
    super.viewDidLoad()


    logInButton.rx
      .tap
      .bind(to: viewModel.inputs.logInButtonDidTap)
      .disposed(by: disposeBag)


    dniTextField.rx
      .text
      .bind(to: viewModel.inputs.dniChanged)
      .disposed(by: disposeBag)

    passwordTextField.rx
      .text
      .bind(to: viewModel.inputs.passwordChanged)
      .disposed(by: disposeBag)


    /*viewModel.outputs.isLoginButtonEnabled
      .drive(onNext: { [weak self] isEnabled in
        guard let `self` = self else { return }
        self.logInButton.isEnabled = isEnabled
      })
      .disposed(by: disposeBag)
    */

    viewModel.outputs.logIn
      .drive(onNext: { [weak self] user in
        guard let `self` = self else { return }
        self.performSegue(withIdentifier: "showMainController", sender: user)
      })
      .disposed(by: disposeBag)
  }

  override func awakeFromNib() {
    super.awakeFromNib()
    viewModel = LoginViewModel()
  }

视图模型:

    var inputs: LoginViewModelInputs { return self }
  var outputs: LoginViewModelOutputs { return self }

  // ---------------------
  // MARK: - Inputs
  // ---------------------
  var dniChanged: BehaviorRelay<String?>
  var passwordChanged: BehaviorRelay<String?>
  var logInButtonDidTap: PublishSubject<Void> = PublishSubject<Void>()


  // ---------------------
  // MARK: - Outpuds
  // ---------------------
  var logIn: Driver<User>
  var isLoginButtonEnabled: Driver<Bool>

  private let disposeBag = DisposeBag()

  public init () {
    dniChanged = BehaviorRelay<String?>(value: "")
    passwordChanged = BehaviorRelay<String?>(value: "")

    let dniObservable = dniChanged.asDriver().filterNil().asObservable()
    let passwordObservable = passwordChanged.asDriver().filterNil().asObservable()

    let dniValidation = dniObservable.map { $0.count > 4 }
    let passwordValidation = passwordObservable.map { $0.count > 3 }

    let validObservable = Observable.combineLatest(dniValidation, passwordValidation) { return $0 && $1 }.filter { $0 }

    isLoginButtonEnabled = validObservable.asDriver(onErrorDriveWith: .empty())

    let loginSuccessObservable = Observable.combineLatest(dniObservable, passwordObservable, validObservable) { (dni, password, valid) -> LogInRequest in
      return LogInRequest(dni: dni, password: password)
    }

    logIn = logInButtonDidTap.withLatestFrom(loginSuccessObservable).flatMapLatest({ request -> Observable<User> in
      return API.shared.post(endpoint: EndPoints.Authorize, type: User.self, body: request)
    }).asDriver(onErrorDriveWith: .empty())
  }

【问题讨论】:

    标签: ios swift mvvm reactive


    【解决方案1】:

    我会说 .empty() 导致 observable 完成,因此订阅被处置。

    我会添加一些 .debug() 指令来确保处理什么以及何时处理。

    【讨论】:

    • 尝试使用 .never() 而不是 .empty() 并且仍然发生错误。顺便说一句,.debug 不存在对吗?
    • 可以,你可以放 .debug() 或 .debug("this will be print on each event")
    • 你是对的。该事件在首次使用后被丢弃。我怎样才能避免这种情况?我将 .just() 改为空,但仍在处理。
    • 我会再次尝试使用 .never(),并尝试找出正在完成并首先处理的内容。
    【解决方案2】:

    我遇到了这个问题,因为按钮大小为零

    【讨论】:

      猜你喜欢
      • 2013-03-01
      • 2020-03-04
      • 2014-10-19
      • 2014-05-07
      • 1970-01-01
      • 1970-01-01
      • 2019-02-10
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多