如何使用ReactiveCocoa 3实现基本的UITextField输入+ UIButton操作场景? [英] How to implement a basic UITextField input + UIButton action scenario using ReactiveCocoa 3?

查看:167
本文介绍了如何使用ReactiveCocoa 3实现基本的UITextField输入+ UIButton操作场景?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我同时是Swift和ReactiveCocoa noob。使用MVVM和Reactive Cocoa v3.0-beta.4框架,我想实现此设置,以了解新RAC 3框架的基础知识。

I'm a Swift and ReactiveCocoa noob at the same time. Using MVVM and Reactive Cocoa v3.0-beta.4 framework, I'd like to implement this setup, to learn the basics of the new RAC 3 framework.

I有一个文本字段,我希望文本输入包含3个以上的字母,以进行验证。如果文本通过验证,则应启用下面的按钮。当按钮收到触地事件时,我想使用视图模型的属性触发一个动作。

I have a text field and I want the text input to contain more than 3 letters, for validation. If the text passes the validation, the button underneath should be enabled. When the button receives the touch down event, I want to trigger an action using the view model's property.

由于目前RAC 3.0测试版的资源非常少,我通过阅读框架的Github repo上的QAs来实现以下内容。以下是我到目前为止所能提出的建议:

Since there are very few resources about RAC 3.0 beta at the moment, I implemented the following by reading the QAs on the framework's Github repo. Here's what I could come up with so far:

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。到目前为止一直很好。

With this setup, the button gets enabled when the view model's text is longer than 3 characters. When the user taps on the button, the view model's action runs and I can get the return value as true. So far so good.

我的问题是:在视图模型的操作中,我想使用其存储的文本属性并更新代码以使用它来发出网络请求。所以,我不需要视图控制器端的输入。我如何需要输入我的Action属性?

My question is: Inside the view model's action, I want to use its stored text property and update the code to make a network request using it. So, I don't need an input from the view controller's side. How can I not require an input for my Action property?

推荐答案

来自 ReactiveCocoa / CHANGELOG.md


一个动作必须指出它接受的输入类型,它产生的输出类型,以及可能发生的错误类型(如果有的话)。

An action must indicate the type of input it accepts, the type of output it produces, and what kinds of errors can occur (if any).

因此,目前无法在没有输入的情况下定义 Action

So currently there is no way to define an Action without an input.

我想你可以声明你不关心输入 AnyObject?并创建 CocoaAction 带方便初始值:

I suppose you could declare that you don't care about input by making it AnyObject? and creating CocoaAction with convenience initialiser:

cocoaAction = CocoaAction(viewModel.action)



补充说明




  • 我不喜欢使用 AnyObject?代替 Bool for validatedTextProducer 。我想你更喜欢它,因为绑定到 buttonEnabled 属性需要 AnyObject?。我宁愿把它放在那里,而不是牺牲我的视图模型的类型清晰度(见下面的例子)。

    Additional remarks

    • I dont't like using AnyObject? instead of Bool for validatedTextProducer. I suppose you preferred it because binding to the buttonEnabled property requires AnyObject?. I would rather cast it there though, instead of sacrificing type clarity of my view model (see example below).

      你可能想要限制执行<视图模型级别以及UI上的code>操作,例如:

      You might want to restrict execution of the Action on the view model level as well as UI, e.g.:

      class ViewModel {
      
          var text = MutableProperty<String>("")
          let action: Action<AnyObject?, Bool, NoError>
      
          // if you want to provide outside access to the property
          var textValid: PropertyOf<Bool> {
              return PropertyOf(_textValid)
          }
      
          private let _textValid = MutableProperty(false)
      
          init() {
              let validation: Signal<String, NoError> -> Signal<Bool, NoError> = map { string in
                  return count(string) > 3
              }
      
              _textValid <~ text.producer |> validation
      
              action = Action(enabledIf:_textValid) { _ in
                  //...
              }
          }
      }
      

      绑定到 buttonEnabled

      func bindSignals() {
          buttonEnabled <~ viewModel.action.enabled.producer |> map { $0 as AnyObject }
          //...
      }
      


    • 这篇关于如何使用ReactiveCocoa 3实现基本的UITextField输入+ UIButton操作场景?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆