ReactiveSwift 简单示例

ReactiveSwift Simple Example

我读过 documentation, gone through their wonderful Playground example, searched S.O., and reached the extent of my 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 使用 SomeModel 中的值初始化 SomeViewController,然后在 SomeModel 中的值发生变化时更新 SomeViewController

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

我意识到 ReactiveSwift 比我在此示例中试图实现的要多得多,但如果有人可以使用它来帮助我入门,我将不胜感激。我希望一旦我得到这部分,剩下的就只是 "click".

首先,您需要在模型中使用 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 所做的那样。