ReactiveCocoa 4的简单UIGestureRecogniser示例

时间:2016-01-08 19:37:19

标签: ios swift swift2 reactive-cocoa reactive-cocoa-4

努力让一个简单的ReactiveCocoa 4示例工作。

  • 我的层次结构中的视图有平移手势识别器。
  • 我的触摸事件的目标类(假设我想根据触摸位置生成网络数据包)。

所以看起来我想要从我的手势识别器创建信号,映射以提取相对于某个视图的触摸位置,然后让我的目标类观察此信号(或者只是有一些调用方法的最终subscribeNext块在我的目的地课上。)

然而,似乎没有任何工作可用,也找不到好的榜样。

我想我应该写这样的东西(伪代码)

panRecognizer
    .rac_gestureSignal()
    .map { (pgr:UIPanGestureRecognizer) -> CGPoint in
        return pgr.locationInView(self.someUiView)
    }.subscribeNext { (location: CGPoint) -> Void in
        self.someNetworkDelegate.updatePosition(location)
    }

这样的事情是否可能(看起来很简单)?我是否可能试图以糟糕的方式使用框架?

2 个答案:

答案 0 :(得分:3)

你真的真的在那附近。

但由于RACSignal CGPoint不是CGPoint,因此NSValue不能panRecognizer.rac_gestureSignal() .map({ [unowned self] (pgr: AnyObject!) -> NSValue! in let pgr = pgr as! UIPanGestureRecognizer return NSValue(CGPoint: pgr.locationInView(self.someUiView)) }).subscribeNext({[unowned self] locationValue in let location = locationValue.CGPointValue self.someNetworkDelegate.updatePosition(location) }) 。一般来说,在ReactiveCocoa 2世界中,你可以通过明确装箱和取消装箱类型来解决这个问题,例如RACSignal并进行相当多的投射:

SignalProducer

但是,通过将extension SignalProducer { func castSignal<T>() -> SignalProducer<T, Error> { return self.map({ $0 as! T }) } func cantError() -> SignalProducer<Value, NoError> { // If we inline this, Swift will try to implicitly return the fatalError // expression. If we put an explicit return to stop this, it complains // it can never execute. One is an error, the other a warning, so we're // taking the coward's way out and doing this to sidestep the problem. func swallowError(error: Error) -> SignalProducer<Value, NoError> { fatalError("Underlying signal errored! \(error)") } return self.flatMapError(swallowError) } } extension RACSignal { func cast<T>() -> SignalProducer<T, NoError> { return self.toSignalProducer().cantError().map({ $0! }).castSignal() } } 转换为 self.reportTapRecognizer.rac_gestureSignal().cast() .map({ [unowned self] (pgr: UIPanGestureRecognizer) -> CGPoint in return pgr.locationInView(self.someUiView) }).startWithNext({ [unowned self] location in self.someNetworkDelegate.updatePosition(location) }) ,您可以使用所需的好类型。这样做很麻烦,所以我使用以下助手:

map

显然,如果您正在转换可能出错的信号,那么您需要不同的助手,但这适用于此示例。

有了这些,您可以像这样编写代码:

cast

基本你是如何在上面写的。请注意,@font-face { font-family: 'xxx'; src: url('xxx.eot'); src: url('xxx.eot?‪#‎iefix‬') format('embedded-opentype'), url('xxx.woff') format('woff'), url('xxx.ttf') format('truetype'), url('xxx.svg#xxx') format('svg'); font-weight: normal; font-style: normal; } 调用中需要使用类型注释,以便$('#calendar').fullCalendar('getView').start.format('YYYY-MM-DD'); 可以正确推断其返回类型。

答案 1 :(得分:0)

使用RAC4这个应该运行良好..

let gesRec = UIPanGestureRecognizer(target: self, action: "gesRecHandler:")

    view.addGestureRecognizer(gesRec)
    gesRec.rac_gestureSignal().toSignalProducer().map({ (x) -> CGPoint in
        guard let pan = x as? UIPanGestureRecognizer else {return CGPointZero}
        return pan.locationInView(self.view)
    }).startWithNext { (pointInView) -> () in
        print(pointInView)
    }

在RAC4中,有一些与信号有关的变化。因此,您首先需要将RACSignal转换为信号生成器并开始观察它。您可以在FrameworkOverview中了解信号生成器 。这篇文章是关于将RACSignals转换为SignalProducer RACSignalToSignalProducer

的文章