[英]Handling action from UITableViewCell in MVVM
所以我有这个BaseCell
类,它也有这个BaseCellViewModel
。 当然,最重要的是一些FancyViewController
和FancyViewModel
。 这里的情况是BaseCell
有UIButton
,它触发了这个IBAction
方法 - 这很好,很酷,因为我可以做任何我想做的事,但是......我不知道我应该怎么知道FacyViewController
关于一些动作的事实发生在BaseCell
。
我可以在FancViewModel
RACObserve
属性,因为它具有那些单元格视图模型的NSArray
,但是如何监视实际操作并通知在单元格上触发的确切操作?
我想到的第一件事就是授权或通知,但由于我们的项目中有RAC ,所以不使用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
上注册一些内容来实际监听 BaseCellViewModel
上RACCommand
执行?
单元可以通过几种方式与视图控制器通信。 常见的是通过授权。 让单元格声明一个公共委托,例如:
// 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]
}
UITableViewCell是易失性,可重用的组件。 它们来去匆匆,你的按钮也可以。
如何跟随@danh建议并且一旦控制在View Controller中,就以编程方式制定RAC信号。
因为我觉得宁愿属于RxSwift阵营:)我无法提供源代码片段,但这个答案可能就是我的意思。
由于您已在BaseCellViewModel
拥有RACCommand
,因此您可以使用其中一个便利信号。 例如,您可以使用executing
信号跟踪其状态:
[baseCellViewModel.showAction.executing subscribeNext:^(NSNumber *executing) {
//do something if the command is executing
}];
如果您需要,与RACObserve
绑定RACObserve
可以正常工作。
您还可以从命令的基础信号中获取最新值(但是在您发布的代码中它将不起作用,因为您使用[RACSignal empty]
并且不发送任何“next”值):
[[baseCellViewModel.command.executionSignals switchToLatest] subscribeNext:^(id x) {
//do something with the value
}];
请注意,在创建BaseCellViewModel
时应该订阅此信号,而不是在configureWithViewModel
因为后者将被多次调用(导致许多订阅相同的信号)。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.