objective-c - react 性 cocoa : eliminate state in subscribeNext: block

标签 objective-c reactive-programming reactive-cocoa

我的 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:]但没有完全得到它。

最佳答案

self.viewModel.searchMode 执行操作时,您需要更改三个不同的值,因此我认为您要做的第一件事是 split the signal并分别取出它们。

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

隐藏状态很简单:

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

我用了distinctUntilChanged上面是因为你对 Collection View y 偏移量的信号似乎是“如果 searchModeYES 则为 0,否则最后一个非零值”。如果 searchMode 信号的值连续为 YESNO,您最终也会在偏移值流中出现重复,这会导致使用 replayLast 来获取您想要的值。 distinctUntilChanged 仅传递表示从 YESNO 转换的值,反之亦然。

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

每当 searchMode 转换YES 时,这应该将 0 y 值插入到流中,并采用每当它转换为 NO 时,之前的值(当然,可以从其他地方更新)。

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

RAC(self.searchBar, DLShouldBeFirstResponder) = searchModeSig;

您将 becomeFirstResponderresignFirstResponder 调用转换为伪属性,如下所示:

@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

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

关于objective-c - react 性 cocoa : eliminate state in subscribeNext: block,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19809944/

相关文章:

iphone - 如何设置 cell.imageview 框架

java - 从 projectreactor 使用 Flux 时生成和处理异常的正确方法是什么

swift - 将闭包作为参数传递时,ReactiveCocoa 保留循环

ios - Prefix.pch ReactiveCocoa/RACEXTScope.h 文件未找到错误

swift - ReactiveSwift Action observeResult 没有像应该的那样返回失败

ios - 为什么标签栏不显示在我的 View Controller 上?

iphone - 从 coredata 获取数据时出错?

rxjs - Rx - 如何应用于流distinctUntilChanged,允许在一段时间后发出重复的项目?

ios - 如何隐藏 iPhone 导航栏上的 'Back' 按钮?

scala - RxScala 中 FRP 的 Event 和 Behavior 对应的概念是什么?