在iOS中,要实现表格数据展示,最常用的做法就是使用UITableView。UITableView继承自UIScrollView,因此支持垂直滚动,而且性能极佳。

UITableView有两种样式:

  • 一列显示:UITableViewStylePlain
  • 分组显示:UITableViewStyleGrouped

tableView展示数据的过程

 1.调用数据源的下面方法得知一共有多少组数据

- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView;

2.调用数据源的下面方法得知每一组有多少行数据

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section;

3.调用数据源的下面方法得知每一行显示什么内容

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath;

常见的属性

  1. // 表格行线条的颜色
  2. self.tableView.separatorColor = [UIColor colorWithRed:/255.0 green:/255.0 blue: alpha:/255.0];
  3. // 显示表格行线条的样式,UITableViewCellSeparatorStyleNone为没有线条
  4. self.tableView.separatorStyle = UITableViewCellSeparatorStyleSingleLine;
  5.  
  6. // 表格的头部控件(直接显示表格的最顶部),一般用来显示广告
  7. self.tableView.tableHeaderView = [UIButton buttonWithType:UIButtonTypeContactAdd];
  8. // 表格的底部控件,一般用来加载更多数据
  9. self.tableView.tableFooterView = [[UISwitch alloc] init];

// 行选中为透明

cell.selectionStyle=UITableViewCellSeparatorStyleNone;

Cell的重用代码

UITableViewCell有个NSString *reuseIdentifier属性,可以在初始化UITableViewCell的时候传入一个特定的字符串标识来设置reuseIdentifier(一般用UITableViewCell的类名)。当UITableView要求dataSource返回UITableViewCell时,先通过一个字符串标识到对象池中查找对应类型的UITableViewCell对象,如果有,就重用,如果没有,就传入这个字符串标识来初始化一个UITableViewCell对象
  1. - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
  2. {
  3. // 1.定义一个cell的标识。static修饰局部变量:可以保证局部变量只分配一次存储空间(只初始化一次)
  4. static NSString *ID = @"mjcell";
  5.  
  6. // 2.从缓存池中取出cell
  7. UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:ID];
  8.  
  9. // 3.如果缓存池中没有cell
  10. if (cell == nil) {
  11. cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:ID];
  12.  }
  13.  
  14. // 4.设置cell的属性...
  15. return cell;
  16. }

右边索引条

已经有相应的数据源,实现即可

  1. /**
  2. * 返回右边索引条显示的字符串数据
  3. */
  4. - (NSArray *)sectionIndexTitlesForTableView:(UITableView *)tableView
  5. {
  6. return [self.groups valueForKeyPath:@"title"];
  7. }

效果:

刷新表格

  1. // 全局刷新(每一行都会重新刷新)
  2. - (void)reloadData;
  3.  
  4. // 局部刷新(使用前提: 刷新前后, 模型数据的个数不变)
  5. - (void)reloadRows:(NSArray *)indexPaths withRowAnimation:(UITableViewRowAnimation)animation;
  6.  
  7. // 局部删除(使用前提: 模型数据减少的个数 == indexPaths的长度)
  8. - (void)deleteRowsAtIndexPaths:(NSArray *)indexPaths withRowAnimation:(UITableViewRowAnimation)animation;

实例:

  1. // 全部刷新
  2. [self.tableView reloadData];
  3.  
  4. // 局部刷新,row指的是第几行,inSection指的是第几组
  5. NSIndexPath *path = [NSIndexPath indexPathForRow:row inSection:];
  6. [self.tableView reloadRowsAtIndexPaths:@[path] withRowAnimation:UITableViewRowAnimationBottom];

滑动删除与新增

  

只需要实现tableview代理即可

  1. /**
  2. * 当tableView进入编辑状态的时候会调用,询问每一行进行怎样的操作(添加\删除)
  3. */
  4. - (UITableViewCellEditingStyle)tableView:(UITableView *)tableView editingStyleForRowAtIndexPath:(NSIndexPath *)indexPath
  5. {
  6. return UITableViewCellEditingStyleDelete;
  7. //return indexPath.row %2 ? UITableViewCellEditingStyleDelete : UITableViewCellEditingStyleInsert;
  8. }

如果显示的是英文Delete,可以通过设置模拟器的语言,同时增加中文语言

选中InfoPlist.strings和InfoPlist.strings

监听点击滑动删除按钮

  1. /**
  2. * 如果实现了这个方法,就自动实现了滑动删除的功能
  3. * 点击了删除按钮就会调用
  4. * 提交了一个编辑操作就会调用(操作:删除\添加)
  5. * @param editingStyle 编辑的行为
  6. * @param indexPath 操作的行号
  7. */
  8. - (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath
  9. {
  10. if (editingStyle == UITableViewCellEditingStyleDelete) { // 提交的是删除操作
  11. // 1.删除模型数据
  12. [self.contacts removeObjectAtIndex:indexPath.row];
  13.  
  14. // 2.刷新表格
  15. // 局部刷新某些行(使用前提:模型数据的行数不变)
  16. [self.tableView deleteRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationTop];
  17.  
  18. // 3.归档
  19. [NSKeyedArchiver archiveRootObject:self.contacts toFile:MJContactsFilepath];
  20. } else if (editingStyle == UITableViewCellEditingStyleInsert) {
  21. // 1.修改模型数据
  22. MJContact *contact = [[MJContact alloc] init];
  23. contact.name = @"jack";
  24. contact.phone = @"";
  25. [self.contacts insertObject:contact atIndex:indexPath.row + ];
  26.  
  27. // 2.刷新表格,使用局部刷新
  28. NSIndexPath *nextPath = [NSIndexPath indexPathForRow:indexPath.row + inSection:];
  29. [self.tableView insertRowsAtIndexPaths:@[nextPath] withRowAnimation:UITableViewRowAnimationBottom];
  30. // [self.tableView reloadData];
  31. }
  32. }

其它属性

// 2.设置每一组头部尾部的高度
    self.tableView.sectionFooterHeight = 0;
    self.tableView.sectionHeaderHeight = 10;
    
    // 3.设置背景色
    self.tableView.backgroundView = nil;
    self.tableView.backgroundColor = IWGlobalBgColor;

常用实例:

  1. #pragma mark - 初始化界面
  2.  
  3. - (void)setupTableView
  4. {
  5. _tableView= [[UITableView alloc] initWithFrame:CGRectMake(, , kScreenWidth, kScreenHeight) style:UITableViewStyleGrouped];;
  6. _tableView.dataSource = self;
  7. _tableView.delegate=self;
  8. _tableView.separatorStyle = UITableViewCellSeparatorStyleNone;
  9. _tableView.tableHeaderView = [self tableHeaderView];
  10. _tableView.tableFooterView = [UIView new];
  11. [self.view addSubview:_tableView];
  12. }
  13.  
  14. // 初始化头部
  15. - (UIView *)tableHeaderView
  16. {
  17.  
  18. }
  19.  
  20. #pragma mark - UITableViewDataSource数据源方法
  21. // 返回分组数
  22. -(NSInteger)numberOfSectionsInTableView:(UITableView *)tableView{
  23. NSLog(@"计算分组数");
  24. return ;
  25. }
  26.  
  27. // 返回每组行数
  28. -(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{
  29. NSLog(@"计算每组(组%i)行数",section);
  30. return group1.contacts.count;
  31. }
  32.  
  33. // 返回每行的单元格
  34. -(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
  35. static NSString *ID = @"RFMeTableViewCell";
  36. UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:ID];
  37. if (cell == nil) {
  38. cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:ID];
  39. }
  40. cell.textLabel.text = @"文字";
  41. cell.imageView.image = [UIImage imageNamed:@"me_phone_icon"];
  42. return cell;
  43. }
  44.  
  45. // 返回每组头标题名称
  46. -(NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section{
  47. NSLog(@"生成组(组%i)名称",section);
  48. return group.name;
  49. }
  50.  
  51. // 返回每组尾部说明
  52. -(NSString *)tableView:(UITableView *)tableView titleForFooterInSection:(NSInteger)section{
  53. NSLog(@"生成尾部(组%i)详情",section);
  54. return group.detail;
  55. }
  56.  
  57. #pragma mark - UITableViewDelegate 代理方法
  58. // 设置分组标题内容高度
  59. -(CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section{
  60. if(section==){
  61. return ;
  62. }
  63. return ;
  64. }
  65.  
  66. // 设置每行高度(每行高度可以不一样)
  67. -(CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath{
  68. return ;
  69. }
  70.  
  71. // 设置尾部说明内容高度
  72. -(CGFloat)tableView:(UITableView *)tableView heightForFooterInSection:(NSInteger)section{
  73. return ;
  74. }
  75.  
  76. // 点击行
  77. -(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath{
  78.  
  79. }

点击效果

  1. - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath*)indexPath
  2. {
  3. //当手指离开某行时,就让某行的选中状态消失
  4. [tableView deselectRowAtIndexPath:indexPath animated:YES];
  5. }

TableView样式

如果带有图标,我们使用系统自带的tableviewCell.ImageView.image来设置的话,会发现,底下的这条线没有包括图标,类型QQ的效果,如:

现在有一个需求,是改成类型微信的显示效果,底部是线包括图标,如:

我们会发现,当tableviewcell.imageView.image 为空的时候,横线是到图标的这个位置的。因而,简单的做法是,不使用系统的,自定义一个imageview,并设置tableviewcell.textLabel的X值。

  1. // 1.设置基本数据
  2. if (item.icon) {
  3. _iconImage.image = [UIImage imageNamed:item.icon];
  4. } else {
  5. _iconImage.frame = CGRectZero;
  6. }
  7. //self.imageView.image = [UIImage imageNamed:item.icon];
  8. self.textLabel.text = item.title;
  9. self.detailTextLabel.text = item.subtitle;

改为textLable的X值

  1. - (void)layoutSubviews
  2. {
  3. [super layoutSubviews];
  4.  
  5. // 调整子标题的x
  6. self.detailTextLabel.x = CGRectGetMaxX(self.textLabel.frame) + ;
  7.  
  8. if (_item.icon) {
  9. self.textLabel.x = ;
  10. }
  11. }

参考完成代码:

  1. //
  2. // MeCommonCell.m
  3. // 99SVR
  4. //
  5. // Created by jiangys on 16/6/2.
  6. // Copyright © 2016年 xia zhonglin . All rights reserved.
  7. //
  8.  
  9. #import "MeCommonCell.h"
  10. #import "CommonCellLabelItem.h"
  11. #import "CommonCellArrowItem.h"
  12.  
  13. @interface MeCommonCell()
  14. /** 箭头 */
  15. @property (nonatomic, strong) UIImageView *rightArrow;
  16. /** 标签 */
  17. @property (nonatomic, strong) UILabel *rightLabel;
  18. /** 图标 这里不使用自带的self.imageView.image,因为底部横线不会包括自带的图标*/
  19. @property(nonatomic, strong) UIImageView *iconImage;
  20. @end
  21.  
  22. @implementation MeCommonCell
  23.  
  24. #pragma mark - 懒加载右边的view
  25. - (UIImageView *)rightArrow
  26. {
  27. if (_rightArrow == nil) {
  28. UIImageView *arrowImageView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"arrow"]];
  29. arrowImageView.size = (CGSize){,};
  30. self.rightArrow = arrowImageView;
  31. }
  32. return _rightArrow;
  33. }
  34.  
  35. - (UILabel *)rightLabel
  36. {
  37. if (_rightLabel == nil) {
  38. self.rightLabel = [[UILabel alloc] init];
  39. self.rightLabel.textColor = COLOR_Text_Gay;
  40. self.rightLabel.font = Font_14;
  41. }
  42. return _rightLabel;
  43. }
  44.  
  45. #pragma mark - 初始化
  46. + (instancetype)cellWithTableView:(UITableView *)tableView
  47. {
  48. static NSString *ID = @"MeCommonCell";
  49. MeCommonCell *cell = [tableView dequeueReusableCellWithIdentifier:ID];
  50. if (cell == nil) {
  51. cell = [[MeCommonCell alloc] initWithStyle:UITableViewCellStyleValue1 reuseIdentifier:ID];
  52. }
  53. return cell;
  54. }
  55.  
  56. - (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier
  57. {
  58. self = [super initWithStyle:style reuseIdentifier:reuseIdentifier];
  59. if (self) {
  60. _iconImage = [[UIImageView alloc] initWithFrame:CGRectMake(,, , self.height)];
  61. _iconImage.contentMode = UIViewContentModeScaleAspectFit;
  62. [self.contentView addSubview:_iconImage];
  63.  
  64. // 设置标题的字体
  65. self.textLabel.font = Font_15;
  66. self.textLabel.textColor = COLOR_Text_Black;
  67. self.detailTextLabel.font = Font_14;
  68.  
  69. // 设置cell的默认背景色
  70. self.backgroundColor = [UIColor whiteColor];
  71. }
  72. return self;
  73. }
  74.  
  75. #pragma mark - 调整子控件的位置
  76. - (void)layoutSubviews
  77. {
  78. [super layoutSubviews];
  79.  
  80. // 调整子标题的x
  81. self.detailTextLabel.x = CGRectGetMaxX(self.textLabel.frame) + ;
  82.  
  83. if (_item.icon) {
  84. self.textLabel.x = ;
  85. }
  86. }
  87.  
  88. - (void)setItem:(CommonCellItem *)item
  89. {
  90. _item = item;
  91.  
  92. // 1.设置基本数据
  93. if (item.icon) {
  94. _iconImage.image = [UIImage imageNamed:item.icon];
  95. } else {
  96. _iconImage.frame = CGRectZero;
  97. }
  98. //self.imageView.image = [UIImage imageNamed:item.icon];
  99. self.textLabel.text = item.title;
  100. self.detailTextLabel.text = item.subtitle;
  101.  
  102. // 2.设置右边的内容
  103. if ([item isKindOfClass:[CommonCellArrowItem class]]) {
  104. self.accessoryView = self.rightArrow;
  105. } else if ([item isKindOfClass:[CommonCellLabelItem class]]) {
  106. CommonCellLabelItem *labelItem = (CommonCellLabelItem *)item;
  107. // 设置文字
  108. self.rightLabel.text = labelItem.text;
  109. // 根据文字计算尺寸
  110. self.rightLabel.size = [labelItem.text sizeMakeWithFont:self.rightLabel.font];
  111. self.accessoryView = self.rightLabel;
  112. } else { // 取消右边的内容
  113. self.accessoryView = nil;
  114. }
  115. }
  116. @end

网摘一些小总结:

  1. //这句话不显示多余的单元格
  2. self.tableView.tableFooterView = [[UIView alloc] initWithFrame:CGRectZero];
  3.  
  4. // 这句话不显示单元格之间的分割线
  5. _tableView.separatorStyle = UITableViewCellSeparatorStyleNone;
  6.  
  7. // 这句话在单元格的最后显示一个箭头
  8. cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;
  9.  
  10. //--- 点击cell的时候 cell不会产生高亮状态 ---
  11. cell.selectionStyle = UITableViewCellSelectionStyleNone;
  12.  
  13. // --- 写在viewdidload里面cell自适应高度 ----
  14. tableView.rowHeight = UITableViewAutomaticDimension; // 自适应单元格高度
  15. tableView.estimatedRowHeight = ; //先估计一个高度
  16.  
  17. // 去掉UItableview headerview黏性(sticky)
  18. - (void)scrollViewDidScroll:(UIScrollView *)scrollView
  19. {
  20. CGFloat sectionHeaderHeight = ;
  21. if (scrollView.contentOffset.y<=sectionHeaderHeight&&scrollView.contentOffset.y>=) {
  22. scrollView.contentInset = UIEdgeInsetsMake(-scrollView.contentOffset.y, , , );
  23. }
  24. else if (scrollView.contentOffset.y>=sectionHeaderHeight) {
  25. scrollView.contentInset = UIEdgeInsetsMake(-sectionHeaderHeight, , , );
  26. }
  27. }
  28.  
  29. // 获取手势点击的是哪一个cell的坐标
  30. NSIndexPath *indexPath = [self.tableView indexPathForCell:((UITableViewCell *)longPress.view)];
  31.  
  32. // 局部刷新
  33. //一个section刷新
  34. NSIndexSet *indexSet=[[NSIndexSet alloc]initWithIndex:];
  35. [tableview reloadSections:indexSet withRowAnimation:UITableViewRowAnimationAutomatic];
  36.  
  37. //一个cell刷新
  38. NSIndexPath *indexPath=[NSIndexPath indexPathForRow: inSection:];
  39. [tableView reloadRowsAtIndexPaths:[NSArray arrayWithObjects:indexPath,nil] withRowAnimation:UITableViewRowAnimationNone];
  40.  
  41. // 关于UITableView如何跳转到最后一行或者任意指定行。
  42. 其实现如下:
  43. [self.chatTableView scrollToRowAtIndexPath:
  44. [NSIndexPath indexPathForRow:[self.chatArray count]- inSection:]
  45. atScrollPosition: UITableViewScrollPositionBottom
  46. animated:NO];
  47.  
  48. // 点击button时获取button所在的cell的indexpath
  49. UIButton *button = sender;
  50. HeroDermaTableViewCell *cell = (HeroDermaTableViewCell *)[[button superview] superview];
  51. NSIndexPath *indexPath = [_tableView indexPathForCell:cell];

分组状态下,顶部留白,解决办法

  1. table.tableHeaderView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 0, CGFLOAT_MIN)];

iOS UI基础-9.0 UITableView基础的更多相关文章

  1. iOS UI进阶-1.0 Quartz2D

    概述 Quartz 2D是一个二维绘图引擎,同时支持iOS和Mac系统.Quartz 2D能完成的工作: 绘制图形 : 线条\三角形\矩形\圆\弧等 绘制文字 绘制\生成图片(图像) 读取\生成PDF ...

  2. [iOS UI进阶 - 6.0] CALayer

    A.基本知识 1.需要掌握的 CALayer的基本属性 CALayer和UIView的关系 position和anchorPoint的作用   2.概念 在iOS中,你能看得见摸得着的东西基本上都是U ...

  3. [iOS UI进阶 - 5.0] 手势解锁Demo

    A.需求 1.九宫格手势解锁 2.使用了绘图和手势事件   code source: https://github.com/hellovoidworld/GestureUnlockDemo     B ...

  4. [iOS UI进阶 - 3.0] 触摸事件的基本处理

    A.需要掌握和练习的 1.介绍事件类型2.通过按钮的事件处理引出view的事件处理3.响应者对象 --> UIResponder --> UIView4.view的拖拽* 实现触摸方法,打 ...

  5. [iOS UI进阶 - 2.0] 彩票Demo v1.0

    A.需求 1.模仿“网易彩票”做出有5个导航页面和相应功能的Demo 2.v1.0 版本搭建基本框架   code source:https://github.com/hellovoidworld/H ...

  6. IOS UI 第十一篇: UITABLEVIEW

    DIY a tableviewcell :   - (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *) ...

  7. IOS UI 第十篇: UITABLEVIEW

    uitableView review yesterday’s knowledge :         folding group :   ------------------------------- ...

  8. iOS UI进阶-4.0 地图与定位

    在移动互联网时代,移动app能解决用户的很多生活琐事,比如 导航:去任意陌生的地方 周边:找餐馆.找酒店.找银行.找电影院   在上述应用中,都用到了地图和定位功能,在iOS开发中,要想加入这2大功能 ...

  9. [iOS UI进阶 - 4.0] 涂鸦app Demo

    A.需求 1.超简易画图,只有一种画笔 2.清屏功能 3.回退功能 4.保存功能 5.使用了cocos2D   code source: https://github.com/hellovoidwor ...

随机推荐

  1. CCPC-Wannafly Winter Camp Day4 Div1 - 夺宝奇兵 - [简单思维题]

    题目链接:https://zhixincode.com/contest/18/problem/A?problem_id=259 题目描述 wls正在玩一个寻宝游戏. 宝藏一共有 $n$ 种,都藏在一个 ...

  2. Codeforces 1032 - A/B/C/D/E - (Undone)

    链接:http://codeforces.com/contest/1032/ 是真的真的真的忍不住想吐槽这题意是真的真的真的读不懂…… A - Kitchen Utensils - [简单数学题] 题 ...

  3. 查询大数据表的效率对比:Linq to SQL、Entity Framework、企业库存储过程、ADO.Net

    最近因为要开发大数据量网站,特作比较. Linq to SQL 查询 记录数:399997Linq to SQL 查询 Milliseconds:1910视图查询 记录数:399997视图查询 Mil ...

  4. 操作系统->数组越界(待完善)

    工作中无意间发现了一段可能存在数组越界的代码, 就在本地仿者写了一段越界的小程序, 先记录下,待以后看操作系统知识的时候,再深入分析 #include <stdio.h> #include ...

  5. js中的事件轮询(event loop)机制

    异步任务指的是,不进入主线程.而进入"任务队列"(task queue)的任务,只有"任务队列"通知主线程,某个异步任务可以执行了,该任务才会进入主线程执行. ...

  6. tomcat端口设置

    在tomcat安装目录下,编辑/conf/server.properties 更改对应的端口: 然后系统重启就可以了.

  7. XSL常用用法语句

    1.xsl的开始语句 <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Tra ...

  8. es内部的多线程异步并发控制

    version元数据(1)第一次创建一个document的时候,它的_version版本号是1:以后,每次对这个document执行修改或者删除操作,都会对这个_version版本号自动加1(2)在删 ...

  9. aws小结

    IAM:亚马逊访问权限控制(AWS Identity and Access Management ) https://www.cnblogs.com/andy9468/p/10635019.html ...

  10. cat 查看文件命令

    查看文件内容 [root@salt-server- .txt ada sada sadas -n 查看文件内容并显示行数 [root@salt-server- .txt ada sada sadas