Skip to content

Instantly share code, notes, and snippets.

What would you like to do?
RAC ViewModel Action after button pressed with textfield char count as button enabled condition
import Result
import ReactiveCocoa
import ReactiveSwift
import UIKit
import XCPlayground
struct ViewModel {
// do not expose the implementation detail
private let (codeSignal, codeSink) = Signal<String, NoError>.pipe()
// change mutable to read-only
// this will not let the changes outside of VM
// and only through the `setCode` method
let code: Property<String>
let openAction: Action<String, String, NoError>
init() {
code = Property(initial: "", then: codeSignal)
let validCodes = Property(capturing: { $0.characters.count > 4})
openAction = Action<String, String, NoError>(enabledIf: validCodes, { code -> SignalProducer<String, NoError> in
return SignalProducer<String, NoError> { observer, _ in
print("Code \(code) will be sent.")
observer.send(value: code)
public func setCode(_ code: String) {
codeSink.send(value: code)
// UI Declarations
let textField = UITextField(frame: CGRect(x: 0, y: 0, width: 360, height: 44))
textField.textColor = .white
textField.text = "P2525"
let button = UIButton(frame: CGRect(x: 0, y: 50, width: 360, height: 44))
button.setTitle("Open", for: .normal)
// Bindings
let viewModel = ViewModel()
// add the `setCode(_:)` function as
// the observer to code text field changes
// When button is pressed, trigger viewModel action with the property value
button.reactive.pressed = CocoaAction(viewModel.openAction, { _ in
return viewModel.code.value
// bind button's isEnabled to action's isEnabled and action's executing
button.reactive.isEnabled <~ Signal.merge(viewModel.openAction.isEnabled.signal, viewModel.openAction.isExecuting.signal)
// Let's assume the user types and then presses the button, for playground use.
textField.sendActions(for: .allEditingEvents)
button.sendActions(for: .touchUpInside)

This comment has been minimized.

Copy link
Owner Author

JaviLorbada commented Apr 6, 2017

Revisions have been made thanks to @eimantas and @sharplet, slack archive for better reference.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.