ios - Rxswift iOS-验证OTP字段并在单击按钮时确认OTP字段

标签 ios swift mvvm rx-swift

我是RxSwift的新手,想在我的项目中实现一项功能。
我必须在提交点击时使用RxSwift使用输入/输出MVVM验证2个字段,即OTP和Confirm OTP。
情况1:如果任何文本字段为空,则应禁用“提交”按钮,因此,如果用户开始键入第一个文本字段,则将启用“提交”按钮(也与确认OTP文本字段相同)
情况2:在提交单击时,我需要验证文本字段是否为空,并在屏幕上显示错误;如果两个文本字段的值都不匹配,则在单击提交按钮时也会显示错误。


let otpChangedText = BehaviorSubject<String>(value:"")
let confirmOtpChangedText = BehaviorSubject<String>(value:"")
let submitButtonTapped = PublishSubject<Void>()

let otp1Validation =  otpChangedText.skipWhile { $0.isEmpty}.map {Validator.isEmpty(string: $0)}

let isValidOtp =  otp1Validation.asDriver(onErrorJustReturn:false)

outputs = Outputs (isValidOTP: isValidOtp)

我已经以某种方式实现了提交按钮禁用状态,但是却不知道如果任何字段为空并且两个文本字段的值都不匹配,我该如何在屏幕上显示错误。
请指导我。谢谢

最佳答案

顺便说一句,从"Intro To Rx"书中:

Subjects provide a convenient way to poke around Rx, however they are not recommended for day to day use.


您不应该将所有这些主题混在一起...

首先,让我们创建您的业务规则:
// Case 1
func eitherFilled(first: String?, second: String?) -> Bool {
    first != nil && !first!.isEmpty || second != nil && !second!.isEmpty
}

// Case 2
func hasError(first: String?, second: String?) -> Bool {
    first == nil || second == nil || first != second
}
您可以独立于Rx或其他任何东西来测试它们,以确保它们正确。
现在创建您的 View 模型:
// Case 1
func buttonEnabled(first: Observable<String?>, second: Observable<String?>) -> Observable<Bool> {
    Observable.combineLatest(first, second, resultSelector: eitherFilled)
}

// Case 2
func displayError(first: Observable<String?>, second: Observable<String?>) -> Observable<Void> {
    Observable.combineLatest(first, second, resultSelector: hasError)
        .filter { $0 }
        .map { _ in }
}
同样,使用RxTest非常容易测试它们。
现在,您可以将 View 模型安装到 View Controller 中,并且知道它们已经起作用,因为您已经对其进行了测试。 (注意:我尚未测试它们。我将其保留给您以确保逻辑正确。)
final class MyViewController: UIViewController {
    @IBOutlet weak var otpField: UITextField!
    @IBOutlet weak var confirmOtpField: UITextField!
    @IBOutlet weak var button: UIButton!
    let disposeBag = DisposeBag()

    override func viewDidLoad() {
        super.viewDidLoad()

        // Case 1
        buttonEnabled(
            first: otpField.rx.text.asObservable(),
            second: confirmOtpField.rx.text.asObservable()
        )
        .bind(to: button.rx.isEnabled)
        .disposed(by: disposeBag)

        // Case 2
        displayError(
            first: otpField.rx.text.asObservable(),
            second: confirmOtpField.rx.text.asObservable()
        )
        .bind {
            finalPresentScene(animated: true) {
                UIAlertController(title: "Error", message: "OTP fileds do not match.", preferredStyle: .alert).scene { $0.connectOK() }
            }
        }
        .disposed(by: disposeBag)
    }
}
因此,通过上述所有操作,您都有两个模型来表示您的业务规则,两个 View 模型将这些业务规则转换为 View 更新,并且 View Controller 用于将 View 模型连接到 View 。
(如果您想了解有关我用于呈现警报的代码的更多信息,请参见此GitHub存储库:https://github.com/danielt1263/CLE-Architecture-Tools)

关于ios - Rxswift iOS-验证OTP字段并在单击按钮时确认OTP字段,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/65776033/

相关文章:

ios - 如何在iOS设置 bundle plist中创建“combobox”类型选择/文本输入?

ios - Swift NSCoding 中的 EXC_BAD_INSTRUCTION

silverlight - 我应该在 Silverlight 项目中使用模型- View - View 模型 (MVVM) 模式吗?

iOS 蓝牙 BLE 连接到设备但显示服务为空

ios - 不同的 UITableViewCells 重叠

ios - Paypal IOS SDK acceptCreditCards 崩溃

ios - CLLocationManager授权消息

ios - 设置按钮图像和标题不会显示标题

c# - 如何通过动态反射在运行时创建 RelayCommand 的实例?

c# - MVVM模式实现