作为一个整体,我对 ReactiveSwift 和 MVVM 非常陌生。我正在尝试验证输入到文本字段中的电话号码并根据验证结果启用/禁用按钮。
在应用程序中,有一个文本字段和一个UIButton
名为提交的按钮。对于电话号码验证,我使用了一个名为[PhoneNumberKit][1]
. 它还提供了一个UITextField
格式化用户输入的子类。
我将一个看起来像这样的解决方案混合在一起。
class ViewController: UIViewController {
@IBOutlet weak var textField: PhoneNumberTextField!
@IBOutlet weak var submitButton: UIButton!
override func viewDidLoad() {
super.viewDidLoad()
textField.becomeFirstResponder()
submitButton.isEnabled = false
let textValuesSignal = textField.reactive.continuousTextValues
SignalProducer(textValuesSignal).start { result in
switch result {
case .value(let value):
print(value)
self.submitButton.isEnabled = self.isPhoneNumberValid(value)
case .failed(let error):
print(error)
self.submitButton.isEnabled = false
case .interrupted:
print("inturrupted")
self.submitButton.isEnabled = false
case .completed:
print("completed")
}
}
}
func isPhoneNumberValid(_ phoneNumberString: String) -> Bool {
do {
let phoneNumber = try PhoneNumberKit().parse(phoneNumberString)
let formattedPhoneNumber = PhoneNumberKit().format(phoneNumber, toType: .e164)
print("Phone number is valid: \(formattedPhoneNumber)")
return true
} catch let error {
print("Invalid phone number: \(error)")
return false
}
}
}
这可以完成工作,但不是很优雅。此外,用户输入和 UI 更改之间存在显着滞后。
另一件事是我上面的解决方案不符合 MVVM。我又试了一次。
class ViewController: UIViewController {
@IBOutlet weak var textField: PhoneNumberTextField!
@IBOutlet weak var submitButton: UIButton!
private let viewModel = ViewModel()
override func viewDidLoad() {
super.viewDidLoad()
textField.becomeFirstResponder()
submitButton.reactive.isEnabled <~ viewModel.isPhoneNumberValid
viewModel.phoneNumber <~ textField.reactive.continuousTextValues
}
}
class ViewModel {
let phoneNumber = MutableProperty("")
let isPhoneNumberValid = MutableProperty(false)
init() {
isPhoneNumberValid = phoneNumber.producer.map { self.validatePhoneNumber($0) } // Cannot assign value of type 'SignalProducer<Bool, NoError>' to type 'MutableProperty<Bool>'
}
private func validatePhoneNumber(_ phoneNumberString: String) -> Bool {
do {
let phoneNumber = try PhoneNumberKit().parse(phoneNumberString)
let formattedPhoneNumber = PhoneNumberKit().format(phoneNumber, toType: .e164)
print("Phone number is valid: \(formattedPhoneNumber)")
return true
} catch let error {
print("Invalid phone number: \(error)")
return false
}
}
}
当我将validatePhoneNumber
函数的结果分配给isPhoneNumberValid
属性时,初始化程序中出现以下错误。
无法将“SignalProducer”类型的值分配给“MutableProperty”类型
我不知道如何将电话号码验证部分与提交按钮的isEnabled
属性和点击操作正确连接。