gpt4 book ai didi

ios - RxSwift - 按下按钮时显示/隐藏警告标签

转载 作者:行者123 更新时间:2023-11-28 10:55:55 24 4
gpt4 key购买 nike

我正在使用 MVVM 模式并尝试仅在用户按下登录按钮时显示警告标签。现在它们没有出现,因为我不知道如何仅在用户操作时显示它们。然后当用户开始编辑时,相应标签的警告应该隐藏。这是我的 ViewController,它处理对 viewModel 的引用:

import UIKit
import RxSwift
import RxCocoa
class RxLoginViewController: UIViewController {

@IBOutlet weak var signInButton: UIButton!
@IBOutlet weak var phoneNumberTextField: UITextField!
@IBOutlet weak var passwordTextField: UITextField!
@IBOutlet weak var phoneWarningLabel: UILabel!
@IBOutlet weak var passwordWarningLabel: UILabel!

fileprivate var viewModel: RxLoginViewModel?
private let disposeBag = DisposeBag()

override func viewDidLoad() {
super.viewDidLoad()

viewModel = RxLoginViewModel(phoneNumber: phoneNumberTextField.rx.text.orEmpty.asDriver(), passwordText: passwordTextField.rx.text.orEmpty.asDriver())
addBindsToViewModel(viewModel: viewModel!)
setupButtons()
}

fileprivate func addBindsToViewModel(viewModel: RxLoginViewModel) {
phoneNumberTextField.rx.text
.orEmpty
.asObservable()
.debug("phoneNumberTextField")
.bindTo(viewModel.phoneNumberText)
.addDisposableTo(disposeBag)

passwordTextField.rx.text
.orEmpty
.asObservable()
.debug("passwordTextField")
.bindTo(viewModel.passwordText)
.addDisposableTo(disposeBag)

viewModel.showPhoneWarning
.asDriver()
.debug("showPhoneWarning")
.drive(onNext: { [weak self] showWarning in
UIView.animate(withDuration: 0.2) {
self?.phoneWarningLabel.isHidden = !showWarning
}}
)
.addDisposableTo(disposeBag)

viewModel.showPasswordWarning
.asDriver()
.debug("showPasswordWarning")
.drive(onNext: { [weak self] showWarning in
UIView.animate(withDuration: 0.2) {
self?.passwordWarningLabel.isHidden = !showWarning
}
})
.addDisposableTo(disposeBag)

viewModel.credentialsValid
.debug("credentialsValid")
.drive(onNext: { [weak self] valid in
self?.signInButton.isEnabled = valid
self?.signInButton.alpha = valid ? 1 : 0.5
})
.addDisposableTo(disposeBag)
}

private func setupButtons() {

signInButton.rx.tap
.bindTo(viewModel!.signInAction)
.addDisposableTo(disposeBag)
}
}

和 View 模型:

class RxLoginViewModel {
let dataManager = DataManager.sharedInstance()

private let disposeBag = DisposeBag()

//MARK: - Model proprties
var phoneNumberText = Variable<String>("")
var passwordText = Variable<String>("")
var signInAction: Variable<Void> = Variable<Void>()

var showPhoneWarning = Variable(false)
var showPasswordWarning = Variable(false)
var credentialsValid: Driver<Bool>
var canLogIn = Variable(false)

init(phoneNumber: Driver<String>, passwordText: Driver<String>) {

let phoneValid = phoneNumber
.distinctUntilChanged()
.throttle(0.3)
.map { ($0 =~ RegEx.phone) }

let passwordValid = passwordText
.distinctUntilChanged()
.throttle(0.3)
.map { ($0.utf8.count > 5) }

credentialsValid = Driver.combineLatest(phoneValid, passwordValid) { $0 && $1 }
phoneNumber.debug("phone number driver")
.drive(onNext: {_ in self.showPhoneWarning.value = false })
.addDisposableTo(disposeBag)
phoneNumber.debug("password driver")
.drive(onNext: {_ in self.showPasswordWarning.value = false })
.addDisposableTo(disposeBag)

credentialsValid.asObservable()
.bindTo(canLogIn)
.addDisposableTo(disposeBag)

// actions handler
signInAction
.asObservable()
.debug("signInAction")
.do(onNext: { _ in
// show warning for any invalid textfield
// filter both valid fields
} )
// sent url request
.subscribe(onNext: { status in

self.dataManager.login(withPhone: self.phoneNumberText.value, email: "", password: self.passwordText.value, success: { ( result ) in
if let response = result as? [String : Any], response["aboutMe"] == nil {
self.dataManager.currentUser().userId = response["id"] as? NSNumber
// self.dataManager.update(.fillProfile)
}
}, failure: { (error) in
// print(error.localizedDescription)

})
})
.addDisposableTo(disposeBag)
}

我应该如何显示任何无效文本字段的警告以及如何过滤我的 ViewModel 中的两个有效字段?

最佳答案

我做 View 模型的方式与您不同,但希望这对您有所帮助...

此处的关键是列出所有可能影响 showPhoneWarning 可观察对象的内容。

例如,如果 signInAction 进入而 phoneNumberText 无效,您希望 observable 发出 true。

让我们将其表示为一个变量:

let invalidPhoneNumberOnTap = source.phoneNumberText
.map { $0.isValidPhoneNumber == false }
.sample(source.signInAction)

如果 phoneNumberText 触发了一个新元素,您还希望 observable 发出 false。

let hideWarning = source.phoneNumberText.map { _ in false }

现在您所要做的就是将这两个合并在一起。您还想确保它以 false 开头,这样警告就不会过早显示。

showPhoneWarning = Observable.of(invalidPhoneNumberOnTap, hideWarning)
.merge()
.startWith(false)

以几乎相同的方式处理 showEmailWarning。

关于ios - RxSwift - 按下按钮时显示/隐藏警告标签,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43593777/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com