简单的尝试一下MVVM + RAC ,这个东西用过的都说好。 VC 控制在200行不是梦。 启动的VC不用管,直接点击屏幕进第二个控制器就好
https://git.oschina.net/wyChirs/MVVM-RAC.git
1.先创建好VC ViewModel View 各自的类
我把UITableView 页抽出来,自定义了一个。外加一个HeadView。主要完成数据的绑定,加载,更新(MJRefresh)
在UITableView的初始化方法中 设置代理,上下拉刷新等
-(instancetype)initWithFrame:(CGRect)frame style:(UITableViewStyle)style{
self = [super initWithFrame:frame style:style];
if (self) {
self.dataArray = [NSMutableArray array];
self.page = 1;
self.delegate = self;
self.dataSource = self;
self.tableHeaderView = self.headView;
self.mj_header = [MJRefreshNormalHeader headerWithRefreshingTarget:self refreshingAction:@selector(refresh)];
self.mj_footer = [MJRefreshAutoNormalFooter footerWithRefreshingTarget:self refreshingAction:@selector(loadMoreData)];
self.mj_footer.automaticallyHidden = YES;
}
return self;
}
上下拉刷新的方法(控制分页)
-(void)refresh{
self.page = 1;
//该方法是执行 refreshCommand 事件 @[self,@(self.page)] 传递的参数 执行该方法后 会触发VM 的 refreshCommand 事件, 并且在取得参数时是按照数组下标对应获取
[self.viewModel.refreshCommand execute:@[self,@(self.page)]];
}
-(void)loadMoreData{
self.page++;
[self.viewModel.refreshCommand execute:@[self,@(self.page)]];
}
在自定义的TableView中 Cell 的点击事件
-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath{
[tableView deselectRowAtIndexPath:indexPath animated:YES];
// 执行 itemClickCommand 传入参数
[self.viewModel.itemClickCommand execute:@[[NSNumber numberWithInteger:indexPath.row],self.headView]];
}
2.最主要的就是 VM的创建
首先确定VM 需要做哪几件事情 :
- 1 网络请求 数据更新
- 2 处理UItableviewCell 的点击事件
声明两个处理事件的对象
/** cell 点击事件 */
@property(nonatomic,strong)RACCommand *itemClickCommand;
/** 刷新数据 */
@property(nonatomic,strong)RACCommand *refreshCommand;
//RACCommand RAC中用于处理事件的类,可以把事件如何处理,事件中的数据如何传递,包装到这个类中,他可以很方便的监控事件的执行过程。
声明 数据源和分页
@property(nonatomic,strong)NSMutableArray *data;
@property(nonatomic,assign)NSInteger page;
初始化事件 并绑定数据
-(void)initViewModel{
@weakify(self);
self.refreshCommand = [[RACCommand alloc] initWithSignalBlock:^RACSignal * _Nonnull(id _Nullable input) {
@strongify(self)
//此处 网络请求获取数据源 上下拉刷新更新数据源
self.page = [input[1] integerValue];
if (self.page == 1) {
[self.data removeAllObjects];
}
for (NSInteger i = 0; i< 5; i++) {
NSDictionary *dic = @{@"name":[NSString stringWithFormat:@"第%ld页怪兽",self.page],@"age":@(i+20)};
Model *mod = [[Model alloc] initWithDictionary:dic];
[self.data addObject:mod];
}
TableView *tableView = input[0];
[tableView reloadData];
[tableView.mj_header endRefreshing];
[tableView.mj_footer endRefreshing];
return [RACSignal empty];
}];
self.itemClickCommand = [[RACCommand alloc] initWithSignalBlock:^RACSignal * _Nonnull(id _Nullable input) {
@strongify(self)
HeadView * view = input[1];
NSInteger index = [input[0] integerValue];
Model *mod = self.data[index];
view.bgLabel.text = [NSString stringWithFormat:@"--%@: %ld岁--",mod.name,mod.age];
return [RACSignal empty];
}];
![MVVM.gif](http:https://img.haomeiwen.com/i1711499/b8eeebb6add0a61d.gif)
}
最后就是在VC中 绑定VM
//最后的VC 仅仅只有50行代码 所有的业务逻辑,网络请求都已经放在了VM中进行。
@interface TestViewController ()
@property(nonatomic,strong) TableView *tableView;
@property(nonatomic,strong) ViewModel *viewModel;
@end
@implementation TestViewController
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view.
self.viewModel = [ViewModel new];
[self bindViewModel];
[self.view addSubview:self.tableView];
}
-(void)bindViewModel{
//KVO 形式 动态监测 数组和 页数
RAC(self.tableView,dataArray) = RACObserve(self.viewModel, self.data);
RAC(self.tableView,page) = RACObserve(self.viewModel, self.page);
[self.viewModel.refreshCommand execute:@[self.tableView,@(1)]];
}
-(TableView*)tableView{
if (!_tableView) {
_tableView = [[TableView alloc] initWithFrame:self.view.bounds style:UITableViewStyleGrouped];
_tableView.viewModel = self.viewModel;
}
return _tableView;
}
随便看了一点别人的demo和资料,深点的还不太懂, 很多类还没有尝过,需要多多尝试。
参考链接:
网友评论