ReactiveSwift - 将`Action`绑定到`UIControl`

时间:2016-09-28 09:41:36

标签: ios swift swift3 reactive

我正在尝试在Action上绑定UISwitch

我使用以下代码

创建了Action
    action = Action<UISwitch, Bool, NoError> { (input: UISwitch) -> SignalProducer<Bool, NoError> in
        return SignalProducer{ (observer, disposable) in
            observer.send(value: input.isOn)
            observer.sendCompleted()
        }
    }

但我无法将其连接到UISwitch

有人可以帮忙吗?

1 个答案:

答案 0 :(得分:1)

还有另一个类CocoaAction,用于包装Action并将它们连接到UIControl(现在位于ReactiveCocoa而非核心ReactiveSwift ,所以如果您使用的是RAC 5,则必须同时导入)

var switch: UISwitch!

//switch.addTarget() does not retain the target, so if we do not
//keep a strong reference here the cocoaAction will be deallocated
//at the end of viewDidLoad() and you will get unrecognized selector 
//errors when the switch tries to execute the action
var switchCocoaAction: CocoaAction!

override func viewDidLoad() {
  let action = Action<UISwitch, Bool, NoError> { (input: UISwitch) -> SignalProducer<Bool, NoError> in
    return SignalProducer { (observer, disposable) in
      observer.send(value: input.isOn)
      observer.sendCompleted()
    }
  }

  //unsafe because it will cast anyObject as! UISwitch
  self.switchCocoaAction = action.unsafeCocoaAction

  switch.addTarget(switchCocoaAction,
    action: CocoaAction.selector,
    forControlEvents: .ValueChanged
  ) 
}

但是,如果您想要的只是一个信号在发生变化时发出switch.isOn值,您可以使用内置rac_signalForControlEvents

更轻松地完成任务。
func switchSignal() -> SignalProducer<Bool, NoError> {
  switch.rac_signalForControlEvents(.ValueChanged) //returns legacy RACsignal
    .toSignalProducer() //legacy RACSignal -> swift SignalProducer
    .flatMapError { _ in .empty } //NSError -> NoError, errors not possible here, so ignore them
    .map { ($0 as! UISwitch).isOn }
}