我试图在ReactiveCocoa和MVVM中表达以下场景。
现在我们有另外的结局:
我遇到了以2结尾的问题。我在我的视图模型中想出了RACCommand,它触发了连接过程。然后在didSelectRowAtIndexPath中执行该命令。
ViewModel:
- (RACCommand *)selectionCommand {
if (!_selectionCommand) {
_selectionCommand = [[RACCommand alloc] initWithSignalBlock:^RACSignal *(id input) {
return [self selectionSignal];
}];
}
return _selectionCommand;
}
- (RACSignal *)selectionSignal {
// not implemented for real
return [[[RACSignal return:@"ASDF"] delay:2.0] logAll];
}
ViewController:
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
UITableViewCell *cell = [self.tableView cellForRowAtIndexPath:indexPath];
UIActivityIndicatorView *activityIndicatorView = [[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleGray];
[activityIndicatorView startAnimating];
cell.accessoryView = activityIndicatorView;
[[self.viewModel.selectionCommand execute:indexPath] subscribeCompleted:^{
[activityIndicatorView stopAnimating];
cell.accessoryView = nil;
}];
}
这显示并隐藏了连接过程中的活动视图,但仅当我等待它完成而不点击其他单元格时。 我要求就如何完成这种行为提供指导。 (这也感觉这不是订阅信号的正确位置,对吧?它应该去viewDidLoad吗?)
答案 0 :(得分:-1)
显然我问了一个错误的问题。它应该说“如何取消RACCommand”。答案是:takeUntil:可以做到(来源:https://github.com/ReactiveCocoa/ReactiveCocoa/issues/1326)。 因此,如果我将命令创建方法修改为如下所示,一切都会像我预期的那样开始工作。现在它再次使用时会自动取消。请注意,allowConcurrentExecution必须设置为YES才能启用此行为,否则信号将发出错误,表示当前未启用RACCommand。
- (RACCommand *)selectionCommand {
if (!_selectionCommand) {
@weakify(self);
_selectionCommand = [[RACCommand alloc] initWithSignalBlock:^RACSignal *(id input) {
@strongify(self);
return [[self selectionSignal] takeUntil:self->_selectionCommand.executionSignals];
}];
_selectionCommand.allowsConcurrentExecution = YES;
}
return _selectionCommand;
}
答案 1 :(得分:-2)
我通过将块操作附加到自定义UITableViewCell子类来完成此操作。我将tableViewCells作为这个subClass的一部分,然后当我在视图控制器中布置我的tableviewcells时,我调用UITabbleViewCell子类中的公开块头,它在这个子类头文件中公开并连接到块操作。自定义UITableViewCell需要一个tapgesture识别器,这将完成这个技巧,只要在你的UITableViewCell自定义子类中你也暴露每个blooth牙齿tableview单元的各种元素,即创建自定义的setter和getters 。这是最简单的方法,它需要大约15行代码和ZERO第三方库。
头文件:
@property (nonatomic, copy) void (^detailsBlock)();
实施档案:
_tapGesture = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(cellTapped:)];
[_tapGesture setDelegate:self];
[_tapGesture setCancelsTouchesInView:FALSE];
[self addGestureRecognizer:_tapGesture];
- (void)cellTapped:(UITapGestureRecognizer*)sender
{
if ([self detailsBlock]) {
[self detailsBlock]();
}
}
使该块适用于viewcontroller中的tableview
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
CustomTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"something" forIndexPath:indexPath];
[cell setDetailsBlock:^{
[self termsButtonPressed];
}];
return cell;
}
-(void)termsButtonPressed
{
//do work
}