day12---UITableView

UITableView 表格视图
一 UITableView
1.1是什么?
以列表的方式展示数据的一种控件,且继承自UISrollView,默认是只能上下滚动;

1.2 使用步骤:
    1)创建UITableView对象,并设置样式;
    2)配置要展示的数据和外观;
        三问:
        1)有几个分区?
        2)每个分区有多少行?
        3)每行的展示的内容是什么?
    3)把它添加到父视图上显示;
见【Demo】-【1-UITableView】
  • (void)viewDidLoad {
    [super viewDidLoad];

    self.automaticallyAdjustsScrollViewInsets = NO;(消除导航控制器对其的影响)

    /********** 创建UITableView ************/
    //UITableViewStylePlain 普通平板样式
    //UITableViewStyleGrouped 分组样式
    UITableView *myTableView = [[UITableView alloc] initWithFrame:CGRectMake(0, 64, screenBounds.size.width, screenBounds.size.height-64) style:UITableViewStylePlain];

    myTableView.delegate = self;
    myTableView.dataSource = self;

    [self.view addSubview:myTableView];
    }

pragma mark -UITableViewDataSource

//三问 【** 重点 **】
//1问,告诉tableView应该显示多少个分区【如果不实现,默认是1个分区】

  • (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView{

    return 1;
    }

//2问,告诉tableView每个分区显示多少行 (该方法有几个分区调用几次)

  • (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{

    return [self.dataArray count];
    }

//3问,告诉tableView每一行显示的具体内容是什么

  • (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{

    //创建静态的标识
    static NSString *cellID = @"MyCell";
    //先从tableView的复用池中去查找没有带cellID标识的单元格;
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:cellID];
    //如果没有找到(复用池中没有符合条件的单元格)
    if (cell == nil) {
    //自己创建一个新的单元格,并初始化单元格的样式,给它加上标识
    cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:cellID];

    }
    //什么是indexPath?indexPath.row?
    MyModel *model = self.dataArray[indexPath.row];
    cell.textLabel.text = model.title;

    //返回符合条件的单元格对象;
    return cell;
    }

1.3 cell简介 【重点】
UITableView的每一行都是一个UITableViewCell类型的对象,通过dataSource的第三问来初始化每一行;

【cell 的复用机制】
当滚动列表时候,部分UITableViewCell会移出窗口;UITableView会将移出去的UITableViewCell放入到一个复用池中,等待重用,当UITableView要求返回UITableViewCell的时候,会先查看复用池,如果池中有未使用的病符合条件的UITableViewCell,就会直接拿来使用,并重新配置这个UITableViewCell展示的内容,然后返回给UITableView,如果池子中没有符合条件的cell,那么则创建一个新的UITableViewCell对象,并返回!

cell的复用机制保证了值创建有限个cell的对象,来显示无限条数据,极大限度的节约了内存的开销,提高了性能,具有极大的借鉴意义;

1.4 UITableView的原理
a 先询问有几个分区

b 根据分区的个数,再多次询问每个分区有多少行,每次询问的时候,会携带分区的section;

c 根据分区号及分区内的行号,再多次询问每一行显示的内容是什么,其中分区号section和行号row会组成一个NSIndexPath的类型,作为参数传递给方法;
  • (void)viewDidLoad {
    [super viewDidLoad];

    //1.请求数据
    [self reloadData];
    //2.创建UITableView
    [self creatUITableView];
    }
    -(void)creatUITableView
    {
    self.automaticallyAdjustsScrollViewInsets = NO;

    //添加背景图片
    UIImageView *bgImg = [[UIImageView alloc] initWithFrame:screenBounds];
    bgImg.image = [UIImage imageNamed:@"5.jpg"];
    // [self.view addSubview:bgImg];

    UITableView *myTableView = [[UITableView alloc] initWithFrame:CGRectMake(0, 64, screenBounds.size.width, screenBounds.size.height-64) style:UITableViewStyleGrouped];
    //必写
    myTableView.delegate = self;
    myTableView.dataSource = self;
    // myTableView.backgroundColor = [UIColor clearColor];
    myTableView.backgroundView = bgImg;

    UIImageView *headerView = [[UIImageView alloc] initWithFrame:CGRectMake(0, 0, 0, 200)];
    headerView.image = [UIImage imageNamed:@"10.jpg"];
    headerView.contentMode = UIViewContentModeScaleAspectFit;
    UIImageView *footerView = [[UIImageView alloc] initWithFrame:CGRectMake(0, 0, 0, 200)];
    footerView.image = [UIImage imageNamed:@"15.jpg"];
    footerView.contentMode = UIViewContentModeScaleAspectFit;
    //给myTableView设置头部视图
    myTableView.tableHeaderView = headerView;
    //给myTableView设置尾部视图
    myTableView.tableFooterView = footerView;

    [self.view addSubview:myTableView];
    }

pragma mark -UITableViewDataSource

//3问 每行显示的内容是什么

  • (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
    {
    static NSString *cellID = @"cellName";

    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:cellID];
    if (cell == nil) {
    //系统给我们提供了3中Cell样式
    // UITableViewCellStyleDefault,
    // UITableViewCellStyleValue1,
    // UITableViewCellStyleValue2,
    // UITableViewCellStyleSubtitle
    cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:cellID];
    }
    //将数据源中的数据,赋值给cell对象展示出来
    UserModel *model = self.dataArray[indexPath.section][indexPath.row];
    //1.显示主标题
    cell.textLabel.text = model.name;
    //2.设置头像
    cell.imageView.image = [UIImage imageNamed:model.iconImage];

    //设置圆角
    cell.imageView.layer.cornerRadius = 8;
    cell.imageView.layer.masksToBounds = YES;
    // cell.imageView.layer.borderColor = (__bridge CGColorRef)([UIColor redColor]);
    // cell.imageView.layer.borderWidth = 10;

    //3.显示副标题
    cell.detailTextLabel.text = model.detailTitle;

    //设置cell右侧的提示样式
    cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;
    cell.backgroundColor = [UIColor clearColor];

    return cell;
    }

/**************************** 相关属性 *******************************/
//设置分区cell的高度
-(CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
return 80;
}

//设置分区的头部视图的标题
-(NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section
{
return [NSString stringWithFormat:@"%c区的头部标题",(char)('A'+section)];

}

//设置分区的尾部标题
-(NSString *)tableView:(UITableView *)tableView titleForFooterInSection:(NSInteger)section
{
return [NSString stringWithFormat:@"%c区的尾部标题",(char)('A'+section)];
}

/****************** 自定义分区的头部,尾部视图 **********************/
//当同时设置分区的头部标题和头部视图,那么优先显示头部视图
-(UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section
{
UILabel *label = [[UILabel alloc] initWithFrame:CGRectZero];
label.text = [NSString stringWithFormat:@"%c区的头部标题",(char)('A'+section)];
label.textAlignment = NSTextAlignmentCenter;
label.font = [UIFont systemFontOfSize:20];
label.backgroundColor = [UIColor cyanColor];
label.textColor = [UIColor redColor];
return label;
}

-(UIView *)tableView:(UITableView *)tableView viewForFooterInSection:(NSInteger)section
{
UILabel *label = [[UILabel alloc] initWithFrame:CGRectZero];
label.text = [NSString stringWithFormat:@"%c区的尾部标题",(char)('A'+section)];
label.textAlignment = NSTextAlignmentCenter;
label.font = [UIFont systemFontOfSize:15];
label.backgroundColor = [UIColor magentaColor];
label.textColor = [UIColor yellowColor];
return label;
}

/********************* 设置分区的头部视图的高度 ****************/
-(CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section
{
return 100;
}

-(CGFloat)tableView:(UITableView *)tableView heightForFooterInSection:(NSInteger)section
{
return 50;
}

//设置右边索引
-(NSArray *)sectionIndexTitlesForTableView:(UITableView *)tableView
{
NSMutableArray *mArr = [NSMutableArray array];
for (int i='A'; i<='Z'; i++) {
NSString *str = [NSString stringWithFormat:@"%c",i];
[mArr addObject:str];
}
return mArr;
}

1.5 UITableViewController 表格视图控制器
UIViewController 管理视图的
UINavigationController 管理多个UIViewController
UITabBarController 即可以管理导航控制器,也可以管理UIViewController

2.1 概念
UITableViewController管理的是一个UITableView;
为了配合UITableView的使用而专门设立的一种特殊控制器,专门用来管理表格视图;

2.2 特点:
1)继承自UIViewController

2)自带的视图已经是UITableView类型,通过 .tableView的属性来访问自己携带的表格视图;

3)控制器本身已经默认遵守了UITableViewDelegate和UITableViewDataSource,并且设置了自己作为该表格式图的代理对象;

4)创建一个表格式图控制器类,继承自UITableViewController,在这个类中专心处理相关代理方法【最主要的三问】;
见【Demo】-【3-UITableViewController】
  • (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {

    //从表格视图的复用池中按照之前注册指定的标识去取可重用的对象;
    //该方法一定会返回一个不为nil的对象;
    //因为:复用池中如果没有可重用的单元格,系统会根据之前注册的类,自动的创建一个单元格对象并返回;
    //如果复用池中有可重用的单元格,系统会直接返回;
    //优点:自动处理一切细节,减少代码量;
    //缺点:这种形式返回的cell对象,只能是默认的样式,其他的三种样式无法设置;
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"MyCell" forIndexPath:indexPath];

    //取出数据源中对应的数据模型,并展示在cell上
    StudentModel *model = self.dataArray[indexPath.section][indexPath.row];
    cell.textLabel.text = model.name;
    cell.imageView.image = [UIImage imageNamed:model.icon];

    cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;

    return cell;
    }

-(CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
return 100;
}

pragma mark -UITableViewDelegate

//一答 【** 重点 **】
//当选中cell的时候,调用该方法
-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
//拿到当前点击的cell所对应的数据模型
StudentModel *model = self.dataArray[indexPath.section][indexPath.row];

//跳转到详情页面
DeatilViewController *dvc = [[DeatilViewController alloc] initWithNibName:@"DeatilViewController" bundle:nil];
//把这个model属性传值给详情页面
dvc.model = model;
__block MyTableViewController *weakself = self;
dvc.block = ^{
    //刷新当前的tableView(系统自带的方法)
    [weakself.tableView reloadData];
    
};
[self.navigationController pushViewController:dvc animated:YES];

}

关于单元格的实现方法:
方式一:
1)定义静态标识
2)根据标识从复用池中取对象
3)如果有,重新赋值后,直接使用
4)如果没有,那么新建一个单元格
方法二:
1)在viewDidLoad中,提前注册号单元格,并指定标识
2)在第三问时,直接从复用池中取,就算没有可重用的单元格,系统内部会根据一早注册号的单元格样式创建单元格,并返回,如果有可重用的,直接返回;
《但方法二生成的单元格样式只能是默认样式,其他样式无法设置》

两种设置cell显示内容的方式: 【** 重点 **】

第一种:
  • (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{

    //创建静态的标识
    static NSString *cellID = @"MyCell";
    //先从tableView的复用池中去查找没有带cellID标识的单元格;
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:cellID];
    //如果没有找到(复用池中没有符合条件的单元格)
    if (cell == nil) {
    //自己创建一个新的单元格,并初始化单元格的样式,给它加上标识
    cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:cellID];

    }
    //什么是indexPath?indexPath.row?
    MyModel *model = self.dataArray[indexPath.row];
    cell.textLabel.text = model.title;

    //返回符合条件的单元格对象;
    return cell;
    }

第二种:
//提前注册cell

[cView registerClass:[MyCell class] forCellWithReuseIdentifier:@"Cell"];

//3问 每一项显示什么内容
-(UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath
{
//从复用池中取有没有符合要求的单元格,如果有,直接返回使用,如果没有,系统会根据之前注册的单元格,自动的创建一个单元格对象,并返回;
MyCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:@"Cell" forIndexPath:indexPath];
//因为UICollectionViewCell是系统自带的cell,所以没有提供样式,没有提供对应的空间,只能设置相关属性;
cell.model = self.dataArray[indexPath.section][indexPath.row];

cell.backgroundColor = [UIColor orangeColor];


return cell;

}

如果cell用xib写的话,提前注册用下面这种写法:
[self.tableView registerNib:[UINib nibWithNibName:@"AppCell" bundle:nil] forCellReuseIdentifier:@"AppCellID"];

  • (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
    AppCell *cell = [tableView dequeueReusableCellWithIdentifier:@"AppCellID" forIndexPath:indexPath];

    cell.model = self.dataArray[indexPath.row];

    return cell;
    }

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 206,126评论 6 481
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 88,254评论 2 382
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 152,445评论 0 341
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 55,185评论 1 278
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 64,178评论 5 371
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,970评论 1 284
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,276评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,927评论 0 259
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 43,400评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,883评论 2 323
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,997评论 1 333
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,646评论 4 322
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,213评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,204评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,423评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,423评论 2 352
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,722评论 2 345

推荐阅读更多精彩内容