ReactiveCocoa基于NSTableView选择状态启用NSButton

时间:2014-01-15 19:00:44

标签: objective-c cocoa reactive-cocoa

我刚开始学习Reactive Cocoa。我正在编写cocoa应用程序,我只想在NSTableView中选择至少一行时启用NSButton。

我在awakeFromNib中使用以下代码

RACSignal *enableSignal = [RACSignal createSignal:^RACDisposable *(id<RACSubscriber> subscriber) {
    @strongify(self);
    if ([self.genreListTableView numberOfSelectedRows] > 0) {
        [subscriber sendNext:@YES];
    } else {
        [subscriber sendNext:@NO];
    }
    return nil;
}];

[self.addButton rac_liftSelector:@selector(setEnabled:)
                      withSignals:enableSignal,nil];

此代码执行正常并在应用启动期间禁用了addButton,因为最初没有选择行。

我希望在选择TableView条目时启用添加按钮。我不知道如何以反应的方式实现。

我可以通过以下方式实现所需的行为。不确定这是否是实现它的正确方法。

     [[self rac_signalForSelector:@selector(tableViewSelectionDidChange:)
                fromProtocol:@protocol(NSTableViewDelegate)] subscribeNext:^(RACTuple *value) {
    NSNotification *notification = value.first;
    if (self.genreListTableView == notification.object) {
        if ([self.genreListTableView numberOfSelectedRows] > 0) {
            [self.addButton setEnabled:TRUE];
        } else {
            [self.addButton setEnabled:FALSE];
        }
    }
}];

我们赞赏任何以反应方式处理要求的建议。

谢谢

2 个答案:

答案 0 :(得分:8)

你走在正确的轨道上。您应该进行一些简化以进行简化。

首先,使用RAC()宏对属性进行简单绑定。

RAC(self.addButton, enabled) = /* A signal */;

这将导致编译错误,因为enabled没有声明的属性(并且getter被命名为isEnabled,而不仅仅是`enabled)。这可以通过以下类别轻松修复:

@interface NSButton (EnabledProp)

@property (assign, nonatomic, getter = isEnabled, setter = setEnabled:) BOOL enabled;

@end

然后,您可以使用另一个宏numberOfSelectedRows直接从表格视图的RACObserve()构建信号。

RAC(self.addButton, enabled) = RACObserve(self.genreListTableView, numberOfSelectedRows);

但是,它必须是BOOL才能使它成为一种绑定。将一种价值转化为另一种价值?那是map:

RAC(self.addButton, enabled) = [RACObserve(self.genreListTableView, numberOfSelectedRows) map:^id (NSNumber * numSelected){
                                          return @([numSelected integerValue] > 0);
}];

来自NSInteger的{​​{1}}在信号中包含在numberOfSelectedRows中,因此请将其解包,与零比较,然后将比较结果重新打包。

答案 1 :(得分:2)

使用Josh Caswell的方法,您可以按如下方式修改观察结果:

[[[RACObserve(self.genreListTableView, numberOfSelectedRows) distinctUntilChanged] deliverOn:[RACScheduler mainThreadScheduler]] subscribeNext:^(NSNumber* numSelected) {
    [self.addButton setEnabled:([numSelected integerValue] > 0)];
}];