您的位置:首页 > 移动开发 > IOS开发

IOS——TableView 中利用Item模型进行 Cell 的开发(1)TableView 篇

2015-08-13 01:40 459 查看
在开发当中,我们遇到过最多的就是 TableView 的界面,小编可以说,基本上每个界面都是用 tableView 做开发的。那么,这么多个 TableView 做开发,遇到的一个问题就是,一直编写对 cell 的控制好麻烦,OC 是一门面向对象的语言,我们要用的是面向对象的思想去开发,MVC 模式,控制器更多的是为试图配置数据,那么如果才能达到快速的用一行代码创建一个 cell 呢,这就是作者今天要说的主题了。

本文章可能各位需要些时间进行消化,本人就是依靠这些技巧达到2周内开发一个 App 并成功上架,这是一套框架,本人目前还在完善,如果有大神觉得那里需要改进,请指点,谢谢,作者很需要成长。

首先,我们要创建一个父类的 TableViewController,这个父类会帮我们处理各种 Item 模型(就是 cell 的数据模型,下文统一叫 Item 模型)的操作。

// 这三个属性放外面主要是方便子类调用的公有属性
@interface FSBaseTableViewController ()
@property (nonatomic,strong) UITableView *tableView;
@property (nonatomic,assign) UITableViewStyle tableViewStyle;
@property (nonatomic,strong) NSMutableArray *dataSource;
@end


@implementation FSBaseTableViewController

#pragma mark - system method
- (void)viewDidLoad {
[super viewDidLoad];
[self.view addSubview:self.tableView];
}

#pragma mark - UITableViewDataSource

- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
return self.dataSource.count;
}

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return [self.dataSource[section] count];
}

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
BaseItem *item = self.dataSource[indexPath.section][indexPath.row];

// FSItemDataDeveliver这个类主要是通过 Item 的类型ItemType 来创建或者从缓存池中查找 Cell
BaseCell *cell = [FSItemDataDeveliver cellWithItem:item tableView:tableView];

cell.item = item;

return cell;
}

#pragma mark - UITableViewDelegate
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{

BaseItem *item = self.dataSource[indexPath.section][indexPath.row];

// 通过Item的 ItemType 的不同类型来识别被点击后的动作
[self actionWithItem:item indexPath:indexPath];

// 取消点击操作放后面,因为可能我们要用到一个方法, [self.tableView indexPathForSelectedRow],这个方法非常有用,用来拿到被点技的 IndexPath,有助于我们拿到被点击 Cell 的位置,但是如果我们将取消点击操作放在签名的话,我们在使用[self actionWithItem:item indexPath:indexPath]来识别操作的时候就拿不到被选中的 IndexPath 了,所以放后面是有好处的
[tableView deselectRowAtIndexPath:indexPath animated:YES];
}

#pragma mark - UITableViewDelegate
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{

BaseItem *item = self.dataSource[indexPath.section][indexPath.row];

[self actionWithItem:item indexPath:indexPath];

[tableView deselectRowAtIndexPath:indexPath animated:YES];
}

- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
BaseItem *item = self.dataSource[indexPath.section][indexPath.row];

return  [self heightWithItemType:item indexPath:indexPath];
}

- (CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section
{
if (self.tableViewStyle == UITableViewStyleGrouped) {
return 0.1;
}else{
return 0;
}
}

- (CGFloat)tableView:(UITableView *)tableView heightForFooterInSection:(NSInteger)section
{
if (self.tableViewStyle == UITableViewStyleGrouped) {
return 9.9;
}else{
return 0;
}
}


#pragma mark - private method
- (CGFloat)heightWithItemType:(BaseItem *)item indexPath:(NSIndexPath *)indexPath
{
if (item.height > 0) { // 如果 Item 在创建的时候就有赋值 height 就用赋值的 height
return item.height;
}

根据 Item 的ItemType 来查找 height 值
switch (item.itemType) {

case ItemTypeHomeRecommend:
case ItemTypeRank:
return FSCell_Home_Height;
break;

case ItemTypeMerchantTop:
case ItemTypeMerchantTasty:
return FSCell_Merchant_Top_Height;
break;

case ItemTypeMerchantMark:
case ItemTypeMerchantComment:
case ItemTypeMerchantOther:
// 这个方法是 AutolayOut 的自适应高的方法
return [self cellAutoLayOutWithItem:item];
break;

default:
break;
}

return FSCell_Default_Height;
}


- (void)actionWithItem:(BaseItem *)item indexPath:(NSIndexPath *)indexPath
{

if (item.option) { //item 的属性,一个 block,用来处理预防操作
item.option();
return;
}

// 根据不同的 Item 类型来处理操作
switch (item.itemType) {
case ItemTypeArrow:
if ([(FSArrowItem *)item desveClass]) { // 判断它需要跳转的控制器的类是否有值
if ([(FSArrowItem *)item judge] && ![Session sharedInstance].isLogin) { // 需要判断用户是否登录状态再跳转,若未登录,则需要用户先登录
[self.navigationController pushViewController:[[PPLoginViewController alloc]init] animated:YES];
return;
}
default:
break;
}
}


#pragma mark  - getter
- (UITableView *)tableView
{
if (!_tableView) {
if (self.tableViewStyle == 0) {
self.tableViewStyle = UITableViewStylePlain;
}else{
self.tableViewStyle = UITableViewStyleGrouped;
}
_tableView = [[UITableView alloc]initWithFrame:CGRectMake(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT - 64 - 49) style:self.tableViewStyle ];
_tableView.dataSource = self;
_tableView.delegate = self;
}

return _tableView;
}

- (NSMutableArray *)dataSource
{
if (!_dataSource) {
_dataSource = [[NSMutableArray alloc]init];
}

return _dataSource;
}

- (NSMutableDictionary *)offScreenCell
{
if (!_offScreenCell ) {
_offScreenCell = [[NSMutableDictionary alloc]init];
}
return _offScreenCell;
}


好了,又到一点四十了,作者要睡觉了,今天把整个父类的 tableView 写出来了,这个算是第一篇,作者预计这个框架可能需要四篇去写,分别有父类的 TabelView,Item 模型,cell 内部的实现,子类 tableView 快速创建 cell,这个框架设计非常好用,可以不断通过出来数据层来更改 UI,block的回调是 Item 的灵魂,明天晚上继续,谢谢。还有,作者的新应用猪猪就快写完了,到时候就有更多时间来完善文章了,希望各位能下载来玩玩,到时候会在文章发布,睡觉了~~~
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: