处理来自MVVM中的UITableViewCell的操作

时间:2016-03-29 19:58:15

标签: ios objective-c mvvm uikit reactive-cocoa

所以我有这个BaseCell类也有BaseCellViewModel。当然,最重要的是FancyViewControllerFancyViewModel。这里的情况是BaseCell上有UIButton触发了这个IBAction方法 - 这很好,而且很酷,因为我可以做任何我想做的事情,但是......我不知道如何让FacyViewController知道BaseCell上发生了一些行动这一事实。

我可以RACObserve FancViewModel中的某个属性,因为它有NSArray这些单元格视图模型,但是如何监控实际操作并通知在单元格上触发的确切操作?

我想到的第一件事是委托或通知,但由于我们的项目中有 RAC ,因此不使用它会非常愚蠢,对吗?

[编辑]到目前为止我做了什么......

因此,事实证明,你可以使用RACCommand来实际处理特定按钮上的UI事件。在那种情况下,我添加了:

@property (strong, nonatomic) RACCommand *showAction;

BaseCellViewModel我的简单实现,如:

- (RACCommand *)showAction {
    return [[RACCommand alloc] initWithSignalBlock:^RACSignal *(id input) {
        NSLog(@"TEST");
        return [[RACSignal empty] logAll];
    }];
}

按照这种模式,我必须在我的BaseCell中做一些事情,结果很简单,我最后补充说:

- (void)configureWithViewModel:(JDLBasePostCellViewModel *)viewModel {
    self.viewModel = viewModel;
    self.actionButton.rac_command = self.viewModel.showAction;
}

并且...... 它有效!但是......
每当发生这种情况时,我都需要提出UIActionSheet,只有当我需要当前的parentViewController并且我不会在任何我不知道的地方传递此类信息时,我才会显示现在该做什么。
FancyViewModel拥有私人@property (nonatomic, strong) NSMutableArray <BaseCellViewModel *> *cellViewModels;,但我如何在FancyViewController上注册某些内容以实际倾听,以便在RACCommand上执行BaseCellViewModel

3 个答案:

答案 0 :(得分:1)

单元可以通过几种方式与视图控制器通信。常见的是通过授权。让单元格声明一个公共委托,例如:

// BaseCell.h
@protocol BaseCellDelegate;

@interface BaseCell : UITableViewCell
@property(nonatomic, weak) id<BaseCellDelegate> delegate;
// ...
@end

@protocol BaseCellDelegate <NSObject>
- (void)baseCell:(BaseCell *)cell didReceiveAction:(NSString *)actionName;
@end

当按下按钮时,找出你想告诉代表的内容,然后告诉它:

// BaseCell.m
- (IBAction)buttonWasPressed:(id)sender {
    self.delegate baseCell:self didReceiveAction:@"someAction";
}

然后,在视图控制器中,声明您符合协议:

// FancyViewController.m
@interface FancyViewController () <BaseCellDelegate>

cellForRowAtIndexPath中,设置单元格的委托:

// dequeue, etc
cell.delegate = self;

您现在需要在vc中实现此功能:

- (void)baseCell:(BaseCell *)cell didReceiveAction:(NSString *)actionName {
    // the cell got an action, but at what index path?
    NSIndexPath *indexPath = [self.tableView indexPathForCell:cell];
    // now we can look up our model at self.model[indexPath.row]
}

答案 1 :(得分:0)

UITableViewCell是易失性,可重用的组件。它们来来去去,你的按钮也可以。

如何跟随@danh建议,一旦控制在View Controller中,就会以编程方式制定RAC信号。

因为我觉得自己属于RxSwift阵营:)我无法提供源代码片段,但this answer可能就是我的意思。

答案 2 :(得分:0)

由于RACCommand中已有BaseCellViewModel,您可以使用其便捷信号之一。例如,您可以使用executing信号跟踪其状态:

[baseCellViewModel.showAction.executing subscribeNext:^(NSNumber *executing) {
  //do something if the command is executing
}];

如果您需要,RACObserve的绑定也可以正常工作。

您还可以从命令的基础信号中获取最新值(但是在您发布的代码中它将不起作用,因为您使用[RACSignal empty]并且不发送任何“下一个”值):

 [[baseCellViewModel.command.executionSignals switchToLatest] subscribeNext:^(id x) {
    //do something with the value
  }];

请注意,您应该在创建BaseCellViewModel时订阅此信号,而不是configureWithViewModel,因为后者将被多次调用(导致许多订阅相同的信号)。