2

我的 VC 中有以下代码:

[RACObserve(self.viewModel, searchMode) subscribeNext:^(NSNumber *value) {
    @strongify(self);
    BOOL isSearchMode = [value boolValue];
    self.searchBarView.hidden = !isSearchMode;
    if (isSearchMode) {
        [self.searchBar becomeFirstResponder];
        self.yContentOffset = self.collectionView.contentOffset.y;
        [self.collectionView setContentOffset:CGPointMake(self.collectionView.contentOffset.x, 0) animated:NO];
    } else {
        [self.searchBar resignFirstResponder];
        [self.collectionView setContentOffset:CGPointMake(self.collectionView.contentOffset.x, self.yContentOffset) animated:NO];
    }
}];

yContentOffset我要删除的 VC 属性在哪里。(它在进入搜索模式之前保存内容偏移并在之后恢复它)。

我已经尝试过[RACSignal if: then: else:],但没有完全做到。

4

1 回答 1

3

您需要在何时更改三个不同的值self.viewModel.searchMode,因此我认为您要做的第一件事是拆分信号并分别获取它们中的每一个。

RACSignal * searchModeSig = [[RACObserve(self.viewModel, searchMode) distinctUntilChanged] 
                                 publish] 
                             signal];

hidden状态很简单:

RAC(self.searchBarView, hidden) = [searchModeSig not];

我在distinctUntilChanged上面使用是因为您对集合视图的 y 偏移量的信号似乎是“如果searchMode是0,则为YES最后一个非零值”。如果searchMode信号的值是YESNO连续的,您最终也会在偏移值流中得到重复,这将搞砸使用replayLast来获得您想要的值。distinctUntilChanged仅传递表示从YESto转换的值,NO反之亦然。

RAC(self.collectionView, contentOffset) = 
    [RACSignal if:searchModeSig
             then:[RACSignal return:[NSValue valueWithCGPoint:CGPointMake(self.collectionView.contentOffset.x, 0)]
             else:[RACObserve(self.collectionView, contentOffset) replayLast]];

每当转换到时,这应该将 0y值插入流中,并在转换到 时采用先前的值(当然,它可能已从其他地方更新)。searchMode YESNO

对于搜索栏的第一响应者状态,使用 似乎是合理的subscribeNext:,但您也可以这样做:

RAC(self.searchBar, DLShouldBeFirstResponder) = searchModeSig;

你已经把becomeFirstResponderandresignFirstResponder调用变成了一个伪属性,如下所示:

@interface UIView (DLFirstResponderProp)

@property (assign, nonatomic) BOOL DLShouldBeFirstResponder;

@end


@implementation UIView (DLFirstResponderProp)

- (void)setDLShouldBeFirstResponder:(BOOL)shouldBe
{
    if( shouldBe ){
        [self becomeFirstResponder];
    }
    else {
        [self resignFirstResponder];
    }
}

- (BOOL)DLShouldBeFirstResponder
{
    return [self isFirstResponder];
}

@end

也可能是提升将是从信号到命令式调用的“官方”方式,但我不确定它如何/是否适用于无参数方法。

于 2013-11-06T21:09:39.250 回答