【发布时间】:2014-03-04 23:12:19
【问题描述】:
我正在构建一个可滑动的单元格,向该单元格添加平移手势。基本上,它与邮箱应用程序中的单元格具有相同的外观和感觉,您可以在其中有一个顶视图,您可以向左或向右滑动以在下面显示另一个视图 (revealView)。
我想用响应式方法来构建它,所以我这样做的方式是:
-
首先,当我设置视图和平移手势时,我正在过滤 rac_gestureSignal 以获取手势的当前状态并使用绑定更新顶视图位置(此处简化了一些实现细节)以及隐藏/当手势结束/取消时显示revealView。当 panDirection 或revealView 发生变化时(为了相应地更新revealView 框架),我也会调用setNeedsLayout 来合并来自它们的值的信号,并在单元格重用时删除显示视图:
- (void)setupView { UIPanGestureRecognizer *panGesture = [[UIPanGestureRecognizer alloc] initWithTarget:self action:nil]; panGesture.delegate = self; RACSignal *gestureSignal = [panGesture rac_gestureSignal], *beganOrChangeSignal = [gestureSignal filter:^BOOL(UIGestureRecognizer *gesture) { return gesture.state == UIGestureRecognizerStateChanged || gesture.state == UIGestureRecognizerStateBegan; }], *endOrCancelSignal = [gestureSignal filter:^BOOL(UIGestureRecognizer *gesture) { return gesture.state == UIGestureRecognizerStateEnded || gesture.state == UIGestureRecognizerStateCancelled; }]; RAC(self, contentSnapshotView.center) = [beganOrChangedSignal map:^id(id value) { return [NSValue valueWithCGPoint:[self centerPointForTranslation:[panGesture translationInView:self]]]; }]; [beganOrChangeSignal subscribeNext:^(UIPanGestureRecognizer *panGesture) { [self updateTopViewFrame]; [panGesture setTranslation:CGPointZero inView:self]; }]; [[endOrCancelSignal filter:^BOOL(UIPanGestureRecognizer *gestureRecognizer) { return [self shouldShowRevealView]; }] subscribeNext:^(id x) { [self showRevealViewAnimated:YES]; }]; [[endOrCancelSignal filter:^BOOL(UIPanGestureRecognizer *gestureRecognizer) { return [self shouldHideRevealView]; }] subscribeNext:^(id x) { [self hideRevealViewAnimated:YES]; }]; [[RACSignal merge:@[RACObserve(self, panDirection), RACObserve(self, revealView)]] subscribeNext:^(id x) { [self setNeedsLayout]; }]; [[self rac_prepareForReuseSignal] subscribeNext:^(id x) { [self.revealView removeFromSuperview]; self.revealView = nil; }]; [self addGestureRecognizer:panGesture]; } -
然后,我将公开一个信号属性 (revealViewSignal),该属性将在显示视图显示/隐藏时发送 YES/NO 值。因此,您可以订阅此信号,从而在视图更改其状态时采取行动。在内部,这个信号将是一个 RACSubject 在每个显示/隐藏动画结束后发送下一个事件:
- (void)showRevealViewAnimated:(BOOL)animated { [UIView animateWithDuration:animated ? 0.1 : 0.0 animations:^{ // SHOW ANIMATIONS } completion:^(BOOL finished) { [(RACSubject *)self.revealViewSignal sendNext:@(YES)]; }]; } - (void)hideRevealViewAnimated:(BOOL)animated { [UIView animateWithDuration:animated ? 0.1 : 0.0 animations:^{ // HIDE ANIMATIONS } completion:^(BOOL finished) { [(RACSubject *)self.revealViewSignal sendNext:@(NO)]; }]; }
一切都按预期工作,但我只是想知道这是否是以 RAC 方式构建这种视图的正确方法。此外,还有两个手势识别器委托方法,我很想在上面的相同设置方法中设置,但我无法弄清楚是否可以在这里使用 rac_signalForSelector:fromProtocol: 方法,所以我最终实现了它们一如既往:
- (BOOL)gestureRecognizerShouldBegin:(UIGestureRecognizer *)gestureRecognizer
{
return [self checkIfGestureShouldBegin:gestureRecognizer];
}
- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer
{
return [self checkIfGestureShouldRecognize:gestureRecognizer];
}
任何帮助将不胜感激,谢谢!
【问题讨论】:
标签: ios objective-c functional-programming reactive-cocoa