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
所做的那样。
我读过 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
所做的那样。