ReactiveSwift简单示例

时间:2016-11-28 03:27:19

标签: swift3 reactive-cocoa

我已经阅读了documentation,经历了他们精彩的游乐场示例,搜索了SO,并达到了google-fu的范围,但我不能为我的生活包裹我的头如何使用ReactiveSwift。

鉴于以下内容......

class SomeModel {
    var mapType: MKMapType = .standard
    var selectedAnnotation: MKAnnotation?
    var annotations = [MKAnnotation]()
    var enableRouteButton = false

    // The rest of the implementation...
}

class SomeViewController: UIViewController {

    let model: SomeModel
    let mapView = MKMapView(frame: .zero) // It's position is set elsewhere
    @IBOutlet var routeButton: UIBarButtonItem?

    init(model: SomeModel) {
        self.model = model
        super.init(nibName: nil, bundle: nil)
    }


    // The rest of the implementation...
}

....如何使用ReactiveSwift使用SomeViewController中的值初始化SomeModel,然后只要SomeViewController中的值发生变化,就会更新SomeModel

我之前从未使用过任何反应,但我读过的所有内容都让我相信这应该是可能的。 这让我发疯了。

我意识到ReactiveSwift比我在这个例子中想要实现的更多,但如果有人可以用它来帮助我开始,我将非常感激。我希望一旦我得到这部分,剩下的就是"点击"。

1 个答案:

答案 0 :(得分:19)

首先,您需要在模型中使用MutableProperty而不是普通类型。这样,您就可以观察到对它们的更改。

class Model {
    let mapType = MutableProperty<MKMapType>(.standard)
    let selectedAnnotation = MutableProperty<MKAnnotation?>(nil)
    let annotations = MutableProperty<[MKAnnotation]>([])
    let enableRouteButton = MutableProperty<Bool>(false)
}

在ViewController中,您可以绑定它们并观察那些必要的内容:

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...
}

请注意,MutableProperty同时包含.signal.signalProducer。 如果您立即需要MutableProperty的当前值(例如初始设置),请使用.signalProducer立即发送包含当前值以及任何更改的事件。

如果您只需要对将来的更改做出反应,请使用.signal,它只会发送事件以供将来更改。

Reactive Cocoa 5.0 will add UIKit bindings您可以使用它直接将UI元素绑定到您的反应层,就像示例中使用routeButton一样。