2016-11-28 14 views
9

Przeczytałem documentation, przejrzałem ich wspaniały przykład Placu Zabaw, przeszukano S.O. i osiągnąłem poziom mojego google-fu, ale nie mogę na całe życie obrócić głowę, jak używać ReactiveSwift.ReactiveSwift Prosty przykład

Biorąc pod uwagę następujące ....

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

.... Jak mogę używać ReactiveSwift zainicjować SomeViewController z wartościami od SomeModel, następnie zaktualizować SomeViewController gdy wartości w SomeModel zmiany?

Nigdy wcześniej nie używałam niczego reaktywnego, ale wszystko, co czytam, prowadzi mnie do przekonania, że ​​to powinno być możliwe. To doprowadza mnie do szału.

Zdaję sobie sprawę, że w ReactiveSwift jest znacznie więcej niż to, co próbuję osiągnąć w tym przykładzie, ale jeśli ktoś mógłby go użyć, aby pomóc mi zacząć, byłbym bardzo wdzięczny. Mam nadzieję, że kiedyś zdobędę tę część, reszta po prostu "kliknie".

Odpowiedz

17

Najpierw należy użyć MutableProperty zamiast zwykłych typów w modelu. W ten sposób możesz zaobserwować zmiany w nich.

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

W swojej ViewController można następnie powiązać te i przestrzegać tych jednak konieczne:

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

Zauważ, że MutableProperty ma zarówno .signal jak również .signalProducer. Jeśli natychmiast potrzebujesz aktualnej wartości MutableProperty (np. Do początkowej konfiguracji), użyj .signalProducer, która natychmiast wysyła zdarzenie z bieżącą wartością, jak również wszelkie zmiany.

Jeśli chcesz zareagować na przyszłe zmiany, użyj opcji .signal, która będzie wysyłać zdarzenia tylko dla przyszłych zmian.

Reactive Cocoa 5.0 will add UIKit bindings, którego można użyć do bezpośredniego wiązania elementów interfejsu użytkownika z warstwą reaktywną, tak jak to zrobiono z przykładem routeButton.

+2

To "kliknięcie", które właśnie usłyszałeś, było wszystkim, co miało sens po przeczytaniu Twojej odpowiedzi. Dziękuję za rozbicie go w tym przykładzie, bo to miało znaczenie! – forgot

+0

Cieszę się, że mogę pomóc – MeXx