我有以下设置,一个GridView
由GridViewCell
s 组成.
class GridView : UIView { var gridViewCells: [GridViewCell] = [] let tapHandler: Position -> () init(frame: CGRect, tapHandler: Position -> ()) { self.tapHandler = tapHandler super.init(frame: frame) self.gridViewCells = createCells(self) addCellsToView(self.gridViewCells) } func addCellsToView(cells: [GridViewCell]) { for cell in cells { self.addSubview(cell) } } }
class GridViewCell: UIImageView { let position: Position let tapHandler: Position -> () init(frame: CGRect, position: Position, tapHandler: Position -> ()) { self.position = position self.tapHandler = tapHandler super.init(frame: frame) } func handleTap(sender: UITapGestureRecognizer) { self.tapHandler(self.position) } }
请注意,我省略了一些不太相关的代码部分,只知道在创建单元格时createCells()
,每个单元格都有一个UITapGestureRecognizer
目标handleTap:
,我也在使用:
typealias Position = (Int, Int)
因此,正如您所看到的,每当GridView
获得实例化时,它都会传递一个回调函数tapHandler: Position -> ()
,当用户点击一个单元格时,该函数最终会被单元调用.
现在,我想将tap事件转换为RAC Signal
.我不知道如何处理这个问题,因为我对RAC很新.感谢Colin Eberhardts的博客文章,我设法对构建块有了基本的了解,并实现了这样的自定义信号:
func createSignal() -> Signal{ var count = 0 return Signal { sink in NSTimer.schedule(repeatInterval: 1.0) { timer in sink.sendNext("tick #\(count++)") } return nil } }
我现在基本上只想要一个类似的行为,即发出的事件不是由a触发NSTimer
,而是由handleTap()
函数触发.
你可以通过使用来实现这一点Signal.pipe()
.这为你提供了一个元组signal
,并且observer
与该信号相关联:
let (signal, observer) = Signal.pipe()
你可以像sink
在你的例子中那样使用它(注意这sink
只是observer
:) 的旧术语)
但是,在按钮或手势识别器的情况下,您可以利用RAC 2
扩展.例如:
let signal: SignalProducer<(), NoError> = gestureRecognizer .rac_gestureSignal() .toSignalProducer() .mapError { fatalError("Unexpected error: \(error)"); return () } // errors cannot occur, but because they weren't typed in `RACSignal` we have to explicitly ignore them. .map { _ in () }
或者UIControl.rac_signalForControlEvents
.
我发布了一个gist
扩展,以简化其中的一些常见操作.我希望这很有用!