我在 ReactiveCocoa 2.x.y
上做了很多工作,现在正在尝试迁移到 4.0(我知道在撰写本文时它仍处于 alpha 阶段)。
但是,我很难弄清楚如何做到这一点:
RAC(viewModel, selectedDate) = [[self.view.datePicker rac_signalForControlEvents:UIControlEventsValueChanged] map:^id(UIDatePicker *picker) {
return picker.date
}];
在 RC 3 或 4 中使用 Swift。就好像他们还没有对 UIKit 进行适当的扩展。
然后我想我也许可以做点什么 á la
viewModel.selectedDate <~ view.datePicker.rac_signalForControlEvents(.ValueChanged).toSignalProducer().map({ (x) -> NSDate in
guard let datePicker = x as? UIDatePicker else { return NSDate() }
return datePicker.date
})
View 模型具有此属性的地方:
var selectedDate: MutableProperty<NSDate>
但这会产生各种编译器错误:
Binary operator '<~' cannot be applied to operands of type 'MutableProperty<NSDate>' and 'SignalProducer<NSDate, NSError>'
编辑
所以我已经设法用这个摆脱了编译器错误:
viewModel.selectedDate <~ _mainView.datePicker.rac_signalForControlEvents(.ValueChanged).toSignalProducer()
.flatMapError({ (error) -> SignalProducer<AnyObject?, NoError> in
return .empty
}).map({ (x) -> NSDate in
guard let datePicker = x as? UIDatePicker else { return NSDate() }
return datePicker.date
})
但是这些代码都没有被执行过。生产者似乎没有正确启动,因为这确实被执行了:
_mainView.datePicker.rac_signalForControlEvents(.ValueChanged).toSignalProducer()
.flatMapError({ (error) -> SignalProducer<AnyObject?, NoError> in
return .empty
}).map({ (x) -> NSDate in
guard let datePicker = x as? UIDatePicker else { return NSDate() }
return datePicker.date
}).startWithNext({ (date) -> () in
print("\(date)")
})
编辑2
为了确保其他一切都按预期工作,我有这个:
_mainView.datePicker.rac_signalForControlEvents(.ValueChanged).toSignalProducer().startWithNext { (x) -> () in
guard let datePicker = x as? UIDatePicker else { return }
print("\(datePicker.date)")
}
它会打印出日期的变化。
编辑 3
此外,为了确保 View 模型属性也很好,我有这个:
viewModel.selectedDate.producer.startWithNext { (selectedDate) -> () in
print("Selected date: \(selectedDate)")
}
viewModel.selectedDate = MutableProperty(NSDate())
它也按预期打印。
编辑 4
我的 View 模型如下所示:
class MainViewModel {
var selectedDate: MutableProperty<NSDate>
init() {
selectedDate = MutableProperty(NSDate())
}
}
还有我的 View Controller :
private var viewModel = MainViewModel()
最佳答案
错误的原因是因为你不能绑定(bind)一个可以发出错误的producer
,你需要先处理它们。因为这是从 RACSignal
转换而来的信号,所以无法知道它们是否真的可以发射,所以我要做的是防范这种情况:
viewModel.selectedDate <~ view.datePicker
.rac_signalForControlEvents(.ValueChanged)
.toSignalProducer()
.map { x -> NSDate in
guard let datePicker = x as? UIDatePicker else { return NSDate() }
return datePicker.date
}
.flatMapErrors { error -> SignalProducer<NSDate, NoError> in
fatalError("Unexpected error: \(error)")
return .empty
}
我建议在 SignalProducerType
扩展中创建一个运算符来实现这一点,例如 assumeNoErrors
。
关于ios - 使用 ReactiveCocoa 将 UIKit 与 View 模型绑定(bind) 3/4,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34005109/