#MVVMFramework ###Swift版本地址:https://github.com/lovemo/MVVMFramework-Swift ####本项目交流群:474292335 ####欢迎有兴趣的有好的想法的参与到项目中来
再看了几篇博客后,总结整理下一个快速开发MVVM框架(抛砖引玉),分离控制器代码,降低代码耦合
终于再也不用为ViewController中一坨坨tableView和collectionView的烦人代码忧虑了
代码加入了cell自适应高度代码,配合MJExtension,MJRefresh,AFNetworking等常用开发框架使用更佳,主要用于分离控制器中的代码,降低代码耦合程度,可以根据自己使用习惯调整代码。欢迎来喷,提issues。
// ViewModel基类
@interface BQBaseViewModel : NSObject
@property (nonatomic, weak) UIViewController *viewController;
@property (nonatomic, strong) NSMutableArray *dataArrayList;
+ (instancetype)modelWithViewController:(UIViewController *)viewController;
/**
* 返回指定indexPath的item
*/
- (instancetype)modelAtIndexPath:(NSIndexPath *)indexPath;
/**
* 显示多少组 (当tableView为Group类型时设置可用)
*/
- (NSUInteger)numberOfSections;
/**
* 每组中显示多少行 (用于tableView)
*/
- (NSUInteger)numberOfRowsInSection:(NSUInteger)section;
/**
* 每组中显示多少个 (用于collectionView)
*/
- (NSUInteger)numberOfItemsInSection:(NSUInteger)section;
/**
* 分离加载首页控制器内容 (内部使用)
*/
- (void)getDataList:(NSString *)url params:(NSDictionary *)params success:(void (^)(NSArray *array))success failure:(void (^)(NSError *error))failure;
/**
* 用来判断是否加载成功,方便外部根据不同需求处理 (外部使用)
*/
- (void)getDataListSuccess:(void (^)( ))success failure:(void (^)( ))failure;
@end
/**
* 选中UITableViewCell的Block
*/
typedef void (^DidSelectCellBlock)(NSIndexPath *indexPath, id item) ;
// - - - - - -- - - - - - 创建类 - - - - - -- - - - - -//
@class BQBaseViewModel;
@interface XTableDataDelegate : NSObject <UITableViewDelegate,UITableViewDataSource>
/**
* 初始化方法
*/
- (id)initWithViewModel:(BQBaseViewModel *)viewModel
cellIdentifier:(NSString *)aCellIdentifier
didSelectBlock:(DidSelectCellBlock)didselectBlock ;
/**
* 设置UITableView的Datasource和Delegate为self
*/
- (void)handleTableViewDatasourceAndDelegate:(UITableView *)table ;
/**
* 获取UITableView中Item所在的indexPath
*/
- (id)itemAtIndexPath:(NSIndexPath *)indexPath ;
@end
/**
* 选中UICollectionViewCell的Block
*/
typedef void (^DidSelectCellBlock)(NSIndexPath *indexPath, id item) ;
/**
* 设置UICollectionViewCell大小的Block
*/
typedef CGSize (^CellItemSize)() ;
/**
* 设置UICollectionViewCell间隔Margin的Block
*/
typedef UIEdgeInsets (^CellItemMargin)() ;
// - - - - - -- - - - - - 创建类 - - - - - -- - - - - -//
@class BQBaseViewModel;
@interface XTCollectionDataDelegate : NSObject <UICollectionViewDelegate,UICollectionViewDataSource>
/**
* 设置UICollectionViewCell大小
*/
- (void)ItemSize:(CellItemSize)cellItemSize;
/**
* 设置UICollectionViewCell间隔Margin
*/
- (void)itemInset:(CellItemMargin)cellItemMargin;
/**
* 初始化方法
*/
- (id)initWithViewModel:(BQBaseViewModel *)viewModel
cellIdentifier:(NSString *)aCellIdentifier
collectionViewLayout:(UICollectionViewLayout *)collectionViewLayout
cellItemSizeBlock:(CellItemSize)cellItemSize
cellItemMarginBlock:(CellItemMargin)cellItemMargin
didSelectBlock:(DidSelectCellBlock)didselectBlock ;
/**
* 设置CollectionView的Datasource和Delegate为self
*/
- (void)handleCollectionViewDatasourceAndDelegate:(UICollectionView *)collection ;
/**
* 获取CollectionView中Item所在的indexPath
*/
- (id)itemAtIndexPath:(NSIndexPath *)indexPath ;
@end
由于用到了UITableView+FDTemplateLayoutCell,现在创建的cell自动计算高度,满足日常开发需求。
/**
* tableView的一些初始化工作
*/
- (void)setupTableView
{
__weak typeof(self) weakSelf = self;
self.table.separatorStyle = UITableViewCellSelectionStyleNone;
self.table.tableHander = [[XTableDataDelegate alloc]initWithViewModel:[[BQViewModel alloc]init]
cellIdentifiersArray:@[MyCellIdentifier,MyCellIdentifier2]
didSelectBlock:^(NSIndexPath *indexPath, id item) {
SecondVC *vc = (SecondVC *)[UIViewController viewControllerWithStoryBoardName:@"Main" identifier:@"SecondVCID"];
[weakSelf.navigationController pushViewController:vc animated:YES];
NSLog(@"click row : %@",@(indexPath.row)) ;
}];
}
/**
* collectionView的一些初始化工作
*/
- (void)setupCollectionView
{
// 可用自定义UICollectionViewLayout,默认为UICollectionViewFlowLayout
self.collectionView.contentInset = UIEdgeInsetsMake(-64, 0, 0, 0);
self.collectionView.collectionHander = [[XTCollectionDataDelegate alloc]initWithViewModel:[[BQViewModel2 alloc]init]
cellIdentifier:MyCellIdentifier
collectionViewLayout:nil cellItemSizeBlock:^CGSize {
return CGSizeMake(110, 120);
} cellItemMarginBlock:^UIEdgeInsets {
return UIEdgeInsetsMake(0, 20, 0, 20);
} didSelectBlock:^(NSIndexPath *indexPath, id item) {
NSString *strMsg = [NSString stringWithFormat:@"click row : %zd",indexPath.row];
[[[UIAlertView alloc] initWithTitle:@"提示"
message:strMsg
delegate:self
cancelButtonTitle:@"好的"
otherButtonTitles:nil, nil] show];
}];
}
- 只需实现加载请求以及配置自定义cell和上述代码,就能轻松实现以下效果,最重要的是代码解耦。
- 导入BQViewModel文件,然后在模块代码中新建ViewModel子类,继承BQBaseViewModel类型,实现加载数据等方法。
- 在ViewController中,初始化tableView或者collectionView,根据需要实现block代码,利用XTableDataDelegate或者XTCollectionDataDelegate的初始化方法将block代码和自己实现的ViewModel类型传递到内部,将会自动根据传入的内容去展现数据。
- 利用xib自定义cell,在- (void)configure:customObj:indexPath:方法中根据模型Model内容配置cell展示的数据。
- 如果在使用过程中遇到BUG,希望你能Issues我,谢谢(或者尝试下载最新的代码看看BUG修复没有)
- 如果在使用过程中发现功能不够用,希望你能Issues我,我非常想为这个框架增加更多好用的功能,谢谢
- http://www.ios122.com/tag/mvvm/
- http://ios.jobbole.com/83657/
- http://www.cocoachina.com/ios/20150525/11919.html
- http://www.cocoachina.com/ios/20140716/9152.html
- http://www.cocoachina.com/ios/20150122/10987.html
- http://bifidy.net/index.php/407
- http://www.jianshu.com/p/1e53f09d0f21
- http://www.cocoachina.com/ios/20160108/14911.html