##UITableView 简单介绍:
UITableView 是 iOS 中使用的非常的广泛,使用的频率非常的高。
仔细观察 iOS App 中,除了游戏类的 App 以外,几乎都会用上 UITableview, 因为使用 UITableView 的目的就是要呈现数十笔甚至上百笔的资料给使用者。
本文将介绍 UITableView 的基本使用方法。
UITableView继承自UIScrollView,因此支持垂直滚动,而且性能极佳
1. 关于UITableView的样式的问题:
关于这两种样式的选择:
只有头部,或没哟头部的组可以用Plain,有头部有尾部,或者组与组之间的间隙要很宽的时候,选择Grounped。
2.UITableView 是如何展示数据的:
UITableView需要一个数据源(dataSource)来显示数据
UITableView会向数据源查询一共有多少行数据以及每一行显示什么数据等
没有设置数据源的UITableView只是个空壳
凡是遵守UITableViewDataSource协议的OC对象,都可以是UITableView的数据源
3.UITableView 数据源方法:
4.UITableView 是如何展示数据的
1.设置数据源
a. 我们一般是使用 控制器 ViewController 作为数据源
设置数据源的两种方式
(1)、代码:self.tableView.dataSource = self;
(2)、使用脱线的方式。
b. 设置数据源,要使数据源遵守 < UITableViewDataSource> 这个协议;
所有遵守这个协议的对象都可以作为数据源。
2.调用数据源的下面方法得知一共有多少组数据
(UITableView展示数据的时候需要知道当前有几组? )
(有多少组数据,这个方法就调用多少次)
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView;
3.调用数据源的下面方法得知每一组有多少行数据
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section;
(有多少行,这个方法就掉用多少次)
4.调用数据源的下面方法得知每一行显示什么内容
(有多少个Cell就调用多少次)
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath;
这些内容就都在数据源对象中.
** 建议: 写代理方法的时候, 如果知道返回值, 那么就先写返回值, 然后会更容易找打对应的方法
5、cell (这个是我们的重点)
• UITableView的每一行都是一个UITableViewCell,通过dataSource的tableView:cellForRowAtIndexPath:方法来初始化每一行
• UITableViewCell内部有个默认的子视图:contentView,contentView是UITableViewCell所显示内容的父视图,可显示一些辅助指示视图
• 辅助指示视图的作用是显示一个表示动作的图标,可以通过设置UITableViewCell的accessoryType来显示,默认是UITableViewCellAccessoryNone(不显示辅助指示视图),其他值如下:
UITableViewCell的contentView
• contentView下默认有3个子视图
• 其中2个是UILabel(通过UITableViewCell的textLabel和detailTextLabel属性访问)
• 第3个是UIImageView(通过UITableViewCell的imageView属性访问)
UITableViewCell还有一个UITableViewCellStyle属性,用于决定使用contentView的哪些子视图,以及这些子视图在contentView中的位置
下面是cell的结构示意图:
Cell的重用原理
• iOS设备的内存有限,如果用UITableView显示成千上万条数据,就需要成千上万个UITableViewCell对象的话,那将会耗尽iOS设备的内存。要解决该问题,需要重用UITableViewCell对象
• 重用原理:当滚动列表时,部分UITableViewCell会移出窗口,UITableView会将窗口外的UITableViewCell放入一个对象池中,等待重用。当UITableView要求dataSource返回UITableViewCell时,dataSource会先查看这个对象池,如果池中有未使用的UITableViewCell,dataSource会用新的数据配置这个UITableViewCell,然后返回给UITableView,重新显示到窗口中,从而避免创建新对象
• 还有一个非常重要的问题:有时候需要自定义UITableViewCell(用一个子类继承UITableViewCell),而且每一行用的不一定是同一种UITableViewCell,所以一个UITableView可能拥有不同类型的UITableViewCell,对象池中也会有很多不同类型的UITableViewCell,那么UITableView在重用UITableViewCell时可能会得到错误类型的UITableViewCell
• 解决方案:UITableViewCell有个NSString *reuseIdentifier属性,可以在初始化UITableViewCell的时候传入一个特定的字符串标识来设置reuseIdentifier(一般用UITableViewCell的类名)。当UITableView要求dataSource返回UITableViewCell时,先通过一个字符串标识到对象池中查找对应类型的UITableViewCell对象,如果有,就重用,如果没有,就传入这个字符串标识来初始化一个UITableViewCell对象
Cell的重用代码
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
// 1.定义一个cell的标识
static NSString *ID = @"cell";
// 2.从缓存池中取出cell(查找是否有重用的cell 有就赋值,没有就返回nil)
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:ID];
// 3.如果缓存池中没有cell
if (cell == nil) { // 当 cell 位nil 的时候,就重新创建一个cell
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:ID];
}
// 4.设置cell的属性...
return cell;
}
这个看看就行了后面会详细的介绍
隐藏状态栏
-(BOOL)prefersStatusBarHidden{
return NO;
}
设置专题栏的样式
- (UIStatusBarStyle)preferredStatusBarStyle{
return UIStatusBarStyleDefault; // 这个显示的是黑色
return UIStatusBarStyleLightContent; // 这个显示的是白色
}
自己手动配置颜色和透明度
UIColor *myColor = [UIColor colorWithRed:21 / 255.0 green:153 / 255.0 blue:219 / 255.0 alpha:0.3];(记得要除255)
6.UITableView 常用的方法
1、设置每一组的头部标签
- (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section{
if (section == 0) {
return @"----- 这个是设置的 第0组的 头标题title ------";
} else {
return @"----- 这个是设置的 第1组的 头标题title ------";
}
}
头标签中的英文字母默认是大小的,头部标签,是对一组内容的主要概括,起一个概括的作用
2、设置每一组的尾部标签
- (NSString *)tableView:(UITableView *)tableView titleForFooterInSection:(NSInteger)section{
if (section == 1) {
return @"----- 这个是设置的 第0组的 尾标题 title ------";
} else {
return @"----- 这个是设置的 第1组的 尾标题 title ------";
}
}
尾部标签,一般是用来详细描述 这一组cell 是用来干嘛的,是一个综合性的描述。
3、设置行高的两种方式
第一种方式:
- (void)viewDidLoad {
[super viewDidLoad];
// 统一设置tableView的所有行的行高
self.tableView.rowHeight = 80;
}
这个是进行统一的设置。如果我们要求所有的行高都是一样的我们可以这样设置
这种方式只能对cell 的行高进行统一设置,这个就是他的局限性。
第二种方式:(这个是使用代理方法)
<UITableViewDelegate>
要遵守代理协议,让后设置代理,这样才能调用这个方法
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
if (indexPath.row % 2 == 0) {
return 60;
} else {
return 100;
}
}
使用这个方法可以 设置每行的高度,通过这个 indexPath
值来动态设置
4、设置cell 之间的分隔线
1.1、设置分隔线的的样式
self.tableView.separatorStyle = UITableViewCellSeparatorStyleNone; // 没有分割线
![这里写图片描述](https://img-blog.csdn.net/20150421022902642)
self.tableView.separatorStyle = UITableViewCellSeparatorStyleSingleLine; // 有单一的一根分割线 // 默认效果灰色的
self.tableView.separatorStyle = UITableViewCellSeparatorStyleSingleLineEtched; // 有单一的一根分隔线,带有雕刻效果。
注意:这个我实在没有看到效果。
5、在UITableView的头栏和尾栏设置控件
1.1、头栏 :一般用于放广告
在头栏添加一个开关
self.tableView.tableHeaderView = [[UISwitch alloc] init];
1.2、尾栏:一般用于加载更多内容
在尾栏添加一个 内容添加 的按钮
self.tableView.tableFooterView = [UIButton buttonWithType:UIButtonTypeContactAdd];
关于头栏和尾栏要注意的:
6、设置cell右边的小图标 (附件的类型)
cell.accessoryType = UITableViewCellAccessoryNone;
cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;
cell.accessoryType = UITableViewCellAccessoryCheckmark;
cell.accessoryType = UITableViewCellAccessoryDetailButton;
cell.accessoryType = UITableViewCellAccessoryDetailDisclosureButton;
![这里写图片描述](https://img-blog.csdn.net/20150421024116857)
6、设置cell 的背景色和背景图片
1.1、背景色
cell.backgroundColor = [UIColor redColor];
1.2、背景图片
UIImageView *imgVw = [[UIImageView alloc] init];
imgVw.image = [UIImage imageNamed:@"img_02"];
cell.backgroundView = imgVw;
注意:单背景图片和背景颜色同时存在的时候,背景颜色会被覆盖的。
7、设置cell被选中后的颜色
UIView *bgView = [[UIView alloc] init];
UIColor *myColor = [UIColor colorWithRed:21 / 255.0 green:153 / 255.0 blue:219 / 255.0 alpha:0.3];
bgView.backgroundColor = myColor;
cell.selectedBackgroundView = bgView;
8、设置组的索引标题
- (NSArray *)sectionIndexTitlesForTableView:(UITableView *)tableView
{
return [self.groups valueForKeyPath:@"title"];
}
// 使用kvc 快速生成一个数组
// 使用这个方法 返回一个数组,这个数组就会自动的 生成组的索引标题。
// 数组中是什么内容,索引就是怎么显示的
9、如何动态的修改cell中的数据并进行数据刷新
1、这里我们用的一个弹框来动态的修改 cell 中的数据
1.1、什么时候才要弹框。
当用户选择 cell 的时候,这个时候我们才需要进行弹框。
用户选择cell 的时候,控制器就会调用一这个代理方法。
控制器要遵守这个代理协议<UITableViewDelegate>
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath;
1.2、怎么弹框
通过下面这个代理方法就可以进行弹框
// 当用户触发 tableView 中某一行的时候,就会通知代理self,self就会调用这个方法
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
// 加载模型数据
Heros *modeHero = self.hero[indexPath.row];
// 获取被触发的cell的信息
NSString *des = modeHero.name;
// 创建一个弹框
UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:@"弹框标题" message:dec delegate:self cancelButtonTitle:@"取消" otherButtonTitles:@"确定", @"傻逼",@"逗逼",@"装逼",nil];
// 这是设置弹框的样式
alertView.alertViewStyle = UIAlertViewStylePlainTextInput;
// 将弹框中的输入框中的内容修改为 dec
[alertView textFieldAtIndex:0].text = des;
// 将弹框显示
[alertView show];
}
1.3、监听弹框按钮的点击
弹框后,我们要监听弹框按钮的点击,这个时候我们就需要使用的弹框的代理方法来监听。
我们就需要在上面那个方法中设置代理,我们选择了控制器self作为了代理。
代理就需要遵守这个协议<UIAlertViewDelegate>
在代理中实现这个方法来监听弹框中按钮的点击
// 当用户触发 alertView 的时候中的时候,就会通知代理self,self就会调用这个方法
- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex{
// 判断用户点击的是哪一个按钮,来决定要执行的代码
if (buttonIndex == 1) {
// 1.获取当前弹框的文本框中的内容
NSString *text = [[alertView textFieldAtIndex:0] text];
// 2.将获取的内容赋值给对应的模型数据
Heros *modeHero = self.hero[alertView.tag];
// 2.1 修改模型的数据
modeHero.name = text;
// 3. 重新刷新UITableView
// [self.tableView reloadData]; 这个是刷新TableView的所有的数据
// 这个是只刷新我们要修改的那一行,这样可以提高性能
NSIndexPath *path = [NSIndexPath indexPathForRow:alertView.tag inSection:0];
[self.tableView reloadRowsAtIndexPaths:@[path] withRowAnimation:UITableViewRowAnimationAutomatic];
}
}