【问题标题】:Simple code swift to reactiveswift简单的代码 swift 到响应式swift
【发布时间】:2017-04-10 09:22:13
【问题描述】:

人们如何转换我的代码:

struct CarModel {
    var model: String?
    var make: String?
    var kilowatts: Int?
    var photoURL: String?

    init(model: String, make: String, kilowatts: Int, photoURL: String) {
        self.model = model
        self.make = make
        self.kilowatts = kilowatts
        self.photoURL = photoURL
    }
} 

和:

class CarViewModel {
    private var car: Car?

    static let HPperKW = 1.34102209

    var modelText: String? {
        return car?.model
    }
    var makeText: String? {
        return car?.make
    }
    var horsepowerText: String? {
        guard let kilowatts = car?.kilowatts else { return nil }
        let HP = Int(round(Double(kilowatts) * CarViewModel.HPperKW))
        return "\(HP) HP"
    }
    var titleText: String? {
        guard let make = car?.make, let model = car?.model else { return nil }
        return "\(make) \(model)"
    }
    var photoURL: URL? {
        guard let photoURL = car?.photoURL else { return nil }
        return URL(string: photoURL)
    }

    init(_ car: Car) {
        self.car = car
    }
}

到 ReactiveCocoa/ReactiveSwift。我读完了。有关 Reactive 的文档,但我不明白如何在我的代码中实现 Reactive API。 谁知道我需要怎么做,请告诉我。 还有知道上一版本 ReactiveCocoa/ReactiveSwift 的优秀示例/示例/教程的人,请告诉我。

【问题讨论】:

    标签: swift3 reactive-cocoa-5 reactive-swift


    【解决方案1】:

    ReactiveCocoa 用于将 dynamic 数据(保存在您的视图模型中)绑定到 ViewController 的 UI。如果你的数据不是动态的(如果 viewmodel 在 vi​​ewcontroller 的生命周期内没有改变)你根本不需要使用 reactivecocoa。但是,如果您的 car 变量将发生变化,并且将使用单个视图控制器来显示多辆汽车,那么反应可可将非常有用。您可以使用MutableProperty 类封装动态car 变量,并创建在汽车属性更改时更新ViewController 的信号。

    class CarViewModel {
      let car: MutableProperty<Car>
    
      init(_ car: Car) {
        self.car = MutableProperty(car)
      }
    
      var modelTextSignal: SignalProducer<String, NoError> {
        return car.producer.map { $0.model }
      }
    
      var makeTextSignal: SignalProducer<String, NoError> {
        return car.producer.map { $0.make }
      }
    
      var horsepowerTextSignal: SignalProducer<String, NoError> {
        return car.producer.map { car in
          let HP = Int(round(Double(car.kilowatts) * CarViewModel.HPperKW))
          return "\(HP) HP"
        }
      }
    
      var titleTextSignal: SignalProducer<String, NoError> {
        return car.producer.map {  "\($0.make) \($0.model)" }
      }
    
      var photoURLSignal: SignalProducer<URL?, NoError> {
        return car.producer.map { URL(string: $0.photoURL) }
      }
    }
    

    现在,我们有一堆信号表示 car 数据随时间变化,并且可以使用 ReactiveCocoa 将这些信号绑定到 UI 以便 UI 每次 viewModel.car.value 时自动更新新车数据更新了!

    class CarViewController: UIViewController {
      @IBOutlet modelLabel: UILabel!
      @IBOutlet makeLabel: UILabel!
      @IBOutlet horsepowerLabel: UILabel!
      @IBOutlet titleLabel: UILabel!
      @IBOutlet image: UIImageView!
    
      var viewModel: CarViewModel!
    
      override func viewDidLoad() {
        self.modelLabel.reactive.text <~ self.viewModel.modelTextSignal
        self.makeLabel.reactive.text <~ self.viewModel.makeTextSignal
        self.horsepowerLabel.reactive.text <~ self.viewModel.horsepowerTextSignal
        self.titleLabel.reactive.text <~ self.viewModel.titleTextSignal
        self.viewModel.photoURLSignal.startWithValues { [weak self] url in
          self?.setImageFromUrl(url)
        }
      }
    
      func displayNewCar() {
        self.viewModel.car.value = aRandomCar()
      }
    
      private func setImageFromUrl(url: URL?) {
        //download url and display in UIImageView
      }
      private func aRandomCar() -> Car {
        //return a Car object
      }
    }
    

    所以你可以看到如果你只需要在你的视图控制器中显示一个不变的汽车对象,那么 ReactiveCocoa 是不需要的——但是,如果你的视图模型在视图控制器的整个生命周期中都在变化,那么 reactcocoa 将允许你绑定您的可变数据到 UI,以便您的视图在数据更改时自动更新!

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-01-18
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多