I\'ve read the documentation, gone through their wonderful Playground example, searched S.O., and reached the extent of my google-fu, but I cannot for the life of me wrap my hea
First you'll want to use MutableProperty
instead of plain types in your Model. This way, you can observe changes to them.
class Model {
let mapType = MutableProperty<MKMapType>(.standard)
let selectedAnnotation = MutableProperty<MKAnnotation?>(nil)
let annotations = MutableProperty<[MKAnnotation]>([])
let enableRouteButton = MutableProperty<Bool>(false)
}
In your ViewController, you can then bind those and observe those however necessary:
class SomeViewController: UIViewController {
let viewModel: Model
let mapView = MKMapView(frame: .zero) // It's position is set elsewhere
@IBOutlet var routeButton: UIBarButtonItem!
init(viewModel: Model) {
self.viewModel = viewModel
super.init(nibName: nil, bundle: nil)
}
override func viewDidLoad() {
super.viewDidLoad()
routeButton.reactive.isEnabled <~ viewModel.enableRouteButton
viewModel.mapType.producer.startWithValues { [weak self] mapType in
// Process new map type
}
// Rest of bindings
}
// The rest of the implementation...
}
Note that MutableProperty
has both, a .signal
as well as a .signalProducer
.
If you immediately need the current value of a MutableProperty
(e.g. for initial setup), use .signalProducer
which immediately sends an event with the current value as well as any changes.
If you only need to react to future changes, use .signal
which will only send events for future changes.
Reactive Cocoa 5.0 will add UIKit bindings which you can use to directly bind UI elements to your reactive layer like done with routeButton
in the example.