我在ReactiveCocoa 2.x.y
上做了很多工作,现在我正在使用迁移到4.0(我知道在撰写本文时它仍处于alpha状态)。
然而,我很难搞清楚这是怎么做的:
RAC(viewModel, selectedDate) = [[self.view.datePicker rac_signalForControlEvents:UIControlEventsValueChanged] map:^id(UIDatePicker *picker) {
return picker.date
}];
使用Swift在RC 3或4中。好像他们还没有对UIKit进行适当的扩展。
然后我想我可能会做一些事情
viewModel.selectedDate <~ view.datePicker.rac_signalForControlEvents(.ValueChanged).toSignalProducer().map({ (x) -> NSDate in
guard let datePicker = x as? UIDatePicker else { return NSDate() }
return datePicker.date
})
视图模型具有此属性:
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)")
})
为了确保其他一切按预期工作,我有这个:
_mainView.datePicker.rac_signalForControlEvents(.ValueChanged).toSignalProducer().startWithNext { (x) -> () in
guard let datePicker = x as? UIDatePicker else { return }
print("\(datePicker.date)")
}
打印日期更改只是fint。
此外,为确保视图模型属性也正常,我有:
viewModel.selectedDate.producer.startWithNext { (selectedDate) -> () in
print("Selected date: \(selectedDate)")
}
viewModel.selectedDate = MutableProperty(NSDate())
也按预期打印。
我的视图模型如下所示:
class MainViewModel {
var selectedDate: MutableProperty<NSDate>
init() {
selectedDate = MutableProperty(NSDate())
}
}
我的视图控制器:
private var viewModel = MainViewModel()
答案 0 :(得分:0)
错误的原因是因为您无法绑定可能发出错误的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
。