【发布时间】:2015-07-19 19:43:37
【问题描述】:
我同时是 Swift 和 ReactiveCocoa 的菜鸟。使用 MVVM 和 Reactive Cocoa v3.0-beta.4 框架,我想实现这个设置,以学习新 RAC 3 框架的基础知识。
我有一个文本字段,我希望文本输入包含 3 个以上的字母,以进行验证。如果文本通过验证,则应启用下方的按钮。当按钮接收到按下事件时,我想使用视图模型的属性触发一个动作。
由于目前关于 RAC 3.0 beta 的资源很少,我通过阅读框架的 Github 存储库上的 QA 来实现以下内容。到目前为止,这是我能想到的:
ViewModel.swift
class ViewModel {
var text = MutableProperty<String>("")
let action: Action<String, Bool, NoError>
let validatedTextProducer: SignalProducer<AnyObject?, NoError>
init() {
let validation: Signal<String, NoError> -> Signal<AnyObject?, NoError> = map ({
string in
return (count(string) > 3) as AnyObject?
})
validatedTextProducer = text.producer.lift(validation)
//Dummy action for now. Will make a network request using the text property in the real app.
action = Action { _ in
return SignalProducer { sink, disposable in
sendNext(sink, true)
sendCompleted(sink)
}
}
}
}
ViewController.swift
class ViewController: UIViewController {
private lazy var txtField: UITextField = {
return createTextFieldAsSubviewOfView(self.view)
}()
private lazy var button: UIButton = {
return createButtonAsSubviewOfView(self.view)
}()
private lazy var buttonEnabled: DynamicProperty = {
return DynamicProperty(object: self.button, keyPath: "enabled")
}()
private let viewModel = ViewModel()
private var cocoaAction: CocoaAction?
override func viewDidLoad() {
super.viewDidLoad()
view.setNeedsUpdateConstraints()
bindSignals()
}
func bindSignals() {
viewModel.text <~ textSignal(txtField)
buttonEnabled <~ viewModel.validatedTextProducer
cocoaAction = CocoaAction(viewModel.action, input:"Actually I don't need any input.")
button.addTarget(cocoaAction, action: CocoaAction.selector, forControlEvents: UIControlEvents.TouchDown)
viewModel.action.values.observe(next: {value in
println("view model action result \(value)")
})
}
override func updateViewConstraints() {
super.updateViewConstraints()
//Some autolayout code here
}
}
RACUtilities.swift
func textSignal(textField: UITextField) -> SignalProducer<String, NoError> {
return textField.rac_textSignal().toSignalProducer()
|> map { $0! as! String }
|> catch {_ in SignalProducer(value: "") }
}
使用此设置,当视图模型的文本长度超过 3 个字符时,按钮会启用。当用户点击按钮时,视图模型的动作就会运行,我可以将返回值设为 true。到目前为止一切顺利。
我的问题是:在视图模型的操作中,我想使用其存储的文本属性并更新代码以使用它发出网络请求。所以,我不需要来自视图控制器的输入。我如何不要求我的 Action 属性输入?
【问题讨论】:
-
我觉得这个问题更适合codereview.stackexchange.com。
-
好的,谢谢你的建议。我将编辑我的帖子,删除问题 #1 并将 #2 作为唯一问题。 @JakubVano
-
@davsan 请注意,由于
buttonEnabled绑定到 UI 属性,您应该在主线程上观察它,例如buttonEnabled <~ viewModel.validatedTextProducer |> observeOn(UIScheduler()) -
好的,感谢您的提醒! @memmons
标签: ios swift mvvm reactive-cocoa reactive-cocoa-3