标签:ios uitableview 架构
原文: http://www.chentoo.com/?p=200
iOS 开发中,UITableView 应该是最常用到的了。完成一个UITableView应该实现他的DataSource和Delegate来讲数据Model填充进View(Cell)中,大家也是知晓的。但是一个UITableView应该怎样才能实现良好的架构,其实很多人是不在意的。而这也是一个初学者和一个工作多年的人最大的差别。
空洞的话说完了,怎么做呢?我们就从头开始实现一个UITableView。新建一个工程,DemoTableView修改ViewController.m,给当前视图加入一个UITabelView。
#import "ViewController.h" @interface ViewController () <UITableViewDataSource, UITableViewDelegate> @property (strong, nonatomic) UITableView *tableView; @end @implementation ViewController - (void)viewDidLoad { [super viewDidLoad]; // Do any additional setup after loading the view, typically from a nib. _tableView = [[UITableView alloc] initWithFrame:self.view.bounds]; _tableView.dataSource = self; _tableView.delegate = self; [self.view addSubview:self.tableView]; } @end
// // DemoObject.h // DemoTableView // // Created by xiazhidi on 15/3/12. // #import <Foundation/Foundation.h> @interface DemoObject : NSObject @property (strong, nonatomic) NSString *title; @property (strong, nonatomic) NSString *content; @end
Model层做到这里就完毕了,Model的获取,修改什么的都一股脑丢到ViewController里甚至TableView的DateSoucre里进行。但是合理的架构应该是这样的,我们应该在Model层封装好所有的数据请求和处理逻辑,而只暴露出获取的接口提供给Controller层使用。我们新建一个Category : DemoObject+Api。在这当中封装好Model的获取和处理逻辑。
// // DemoObject+Api.h // DemoTableView // // Created by xiazhidi on 15/3/12. // Copyright (c) 2015年 baixing. All rights reserved. // #import "DemoObject.h" typedef void(^DemoObjectFetchCompletionBlock)(NSArray *demoObjects, NSError *error); @interface DemoObject (Api) + (void)fetchWithCompletionBlock:(DemoObjectFetchCompletionBlock)completionBlock; @end
可以看到,我们提供了一个类方法暴露给Controller层,让它可以方便的获取数据,数据通过Block返回,当然你也可以用Delegate实现,这个看个人习惯。相应的,.m的实现如下:(我们只是造一些假数据,真实应用中肯定要设计从网络获取)
// // DemoObject+Api.m // DemoTableView // // Created by xiazhidi on 15/3/12. // Copyright (c) 2015年 baixing. All rights reserved. // #import "DemoObject+Api.h" @implementation DemoObject (Api) + (void)fetchWithCompletionBlock:(DemoObjectFetchCompletionBlock)completionBlock { NSMutableArray *mArray = [[NSMutableArray alloc] initWithCapacity:10]; for (NSInteger i = 0; i < 10; i++) { DemoObject *demoObject = [[DemoObject alloc] init]; demoObject.title = [NSString stringWithFormat:@"这是第%lu个标题", (unsigned long)i]; demoObject.content = [NSString stringWithFormat:@"这是第%lu个内容", (unsigned long)i]; [mArray addObject:demoObject]; } if (completionBlock) { completionBlock([mArray copy], nil); } } @end
对于UITableView的View层来说,就是我们要建立一个 Cell ,可以用Xib也可以不用。那我们这里就用吧,毕竟正式项目中,autolayout什么的用起来还是方便的。新建DemoTableViewCell,放好两个label,连连线什么的就不讲了。具体可看后面附的源码。关键是,我们需要在cell中,实现cell的配置逻辑。所以我们建立了一个category
// // DemoTableViewCell+Configure.h // DemoTableView // // Created by xiazhidi on 15/3/12. // Copyright (c) 2015年 baixing. All rights reserved. // #import "DemoTableViewCell.h" @class DemoObject; @interface DemoTableViewCell (Configure) - (void)configureWithDemoObject:(DemoObject *)demoObject; @end
// DemoTableViewCell+Configure.m // DemoTableView // // Created by xiazhidi on 15/3/12. // Copyright (c) 2015年 baixing. All rights reserved. // #import "DemoTableViewCell+Configure.h" #import "DemoObject.h" @implementation DemoTableViewCell (Configure) - (void)configureWithDemoObject:(DemoObject *)demoObject { self.titleLabel.text = demoObject.title; self.contentLabel.text = demoObject.content; } @end
暴露了一个接口给Controller来实现view的配置。 这样的优点是,Controller层不会堆积很多的代码让人头痛(想想一个复杂的cell可能会有多少需要配置的UI元素),并且会很方便的方便Cell的复用。
我们再来看看现在Controller层具体实现的代码,层次会十分清晰。
// // ViewController.m // DemoTableView // // Created by xiazhidi on 15/3/12. // Copyright (c) 2015年 baixing. All rights reserved. // #import "ViewController.h" #import "DemoObject+Api.h" #import "DemoTableViewCell+Configure.h" @interface ViewController () <UITableViewDataSource, UITableViewDelegate> @property (strong, nonatomic) UITableView *tableView; @property (strong, nonatomic) NSArray *demos; @end @implementation ViewController - (void)viewDidLoad { [super viewDidLoad]; // Do any additional setup after loading the view, typically from a nib. _tableView = [[UITableView alloc] initWithFrame:self.view.bounds]; _tableView.dataSource = self; _tableView.delegate = self; [_tableView registerNib:[UINib nibWithNibName:@"DemoTableViewCell" bundle:nil] forCellReuseIdentifier:DemoTableViewCellReuseIdentifier]; [self.view addSubview:self.tableView]; __weak ViewController *weakSelf = (ViewController *)self; [DemoObject fetchWithCompletionBlock:^(NSArray *demoObjects, NSError *error) { if (!error) { weakSelf.demos = demoObjects; [weakSelf.tableView reloadData]; } }]; } #pragma mark - UITableViewDataSource - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section { return self.demos.count; } - (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath { return 60.0f; } - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { DemoTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:DemoTableViewCellReuseIdentifier forIndexPath:indexPath]; [cell configureWithDemoObject:self.demos[indexPath.row]]; return cell; } @end
标签:ios uitableview 架构
原文地址:http://blog.csdn.net/chentoo/article/details/44458287