UITableView笔记:
1. UITableView很重要
- 演示, 各种地方都用到了 UITableView
- 打开模拟器的设置界面, 演示到处都是 tableView的使用。
- 查看截图
2. UITableView就是表格控件
- 由行和列来组成
- 提醒: UITableView中每行只有1列
- 每行中保存的都是一个UITableViewCell对象
- UITableView的常见属性
* rowHeight , 可以统一设置所有行的高度
* separatorColor, 分隔线的颜色
* separatorStyle, 分割线的样式
* tableHeaderView, 一般可以放广告
* tableFooterView, 一般可以放加载更多
3. UITableView一般用来展示表格数据、可以滚动(继承自UIScrollView)、性能极佳
* 如果没有UITableView, 实现类似的功能只能自己通过循环创建控件, 性能差
4. UITableView 分两种样式:
1> Plain, 简明样式(不分组的样式)
2> Grouped, 分组的样式
- 无论分组样式还是不分组样式, 其实都能显示分组数据、显示组标题、组描述。
5. 演示案例: 显示单组数据, 通过UITableView显示一些数据,只分一组。
6. 演示案例: 分组显示数据, 通过 if-else来显示不同洲的不同国家。并设置组头标题, 组尾标题(组描述)。
* 演示设置了分组标题以后, 把 UITableView的 style 改成 plain, 然后查看效果。(组标题在分组样式下和不分组样式下的不同效果)
7. 案例: 汽车品牌展示(演示分组显示数据)
- 通过加载 plist 文件的方式演示下面的案例cars_simple.plist文件。
- 拖一个UITableView占满整个屏幕
- UITableView展示数据需要: 数据源对象
8. UITableView数据源对象中的3个重要方法:
一、UITableView展示数据的时候需要知道当前有几组?
- (NSInteger)numberOfSectionsInTableView:(UITableView*)tableView
** 注意: 不实现这个方法默认就是一组。
二、每一组有几行?
- (NSInteger)tableView:(UITableView *)tableViewnumberOfRowsInSection:(NSInteger)section
三、每行显示什么内容?
- (UITableViewCell *)tableView:(UITableView *)tableViewcellForRowAtIndexPath:(NSIndexPath *)indexPath
** 注意: 分析上面的3个数据源方法的执行顺序次数
总结:UITableView使用的基本步骤:
1》设置数据源对象
2》让数据源对象遵守UITableViewDataSource协议
3》实现上面的3个数据源方法
4》通过代理来监听各种事件
9. 建议: 写代理方法的时候, 如果知道返回值,那么就先写返回值, 然后会更容易找到对应的方法
10. 展示单组数据, LOL英雄展示。
- 演示Cell的不同样式效果
- 加载plist数据
- 修改每行的行高:
1> 介绍在 viewDidLoad 中统一设置行高tableView.rowHeight(如果行高都一样,一定要通过这个来设置(高效),不要要代理方法(低效))
tableView.rowHeight
2> 通过代理方法实现:
- (CGFloat)tableView:(UITableView *)tableViewheightForRowAtIndexPath:(NSIndexPath *)indexPath(低效)
3> 通过设置预估行高, 提高tableView的一开始的响应速度
- self.tabelView.estimatedRowHeight
11. UITableViewCell的常见属性:
* imageView
* textLabel
* detailTextLabel
* accessoryType
* accessoryView
* backgroundColor , 设置单元格的背景颜色
* backgroundView, 可以利用这个属性来设置单元格的背景图片, 指定一个UIImageView就可以了。
* selectedBackgroundView , 当某行被选中的时候的背景。
12. UITableView的常见属性:
* rowHeight, 可以统一设置所有行的高度
* separatorColor, 分隔线的颜色
* separatorStyle, 分割线的样式
* tableHeaderView, 一般可以放广告
* tableFooterView, 一般可以放加载更多
13. UITableView中的Cell的重用
* 解决性能问题
* 查看每个"数据源方法"的执行顺序
* 重点查看下面的方法的调用顺序
//这个方法每当有一个cell进入屏幕的时候就调用一次
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath*)indexPath
* 默认情况下, 滚动离开屏幕的Cell会被销毁。(不断的创建销毁对象本身也比较耗费性能)
* 通过缓存池解决cell重用的问题, 离开屏幕的cell不被销毁, 而是被重用。
* 性能优化步骤:
1> 通过一个标识去缓存池中查找是否有对应的cellF
2> 如果有则取出来使用, 如果没有, 则创建一个。
3> 设置cell数据
4> 代码实现重用cell功能。
5> 优化cell_id变量。(注意标识命名要规范)
14. 利用重用cell实现多组汽车品牌展示
一、
* 使用cars_total.plist
* 模型嵌套模型
** 注意, 这里使用的是模型套模型, 所以不能直接使用KVC了。需要通过把字典转模型的代码封装到Group模型中。
二、
* 实现右侧的索引栏
* 通过实现数据源协议的- (NSArray*)sectionIndexTitlesForTableView:(UITableView *)tableView
* 点击右侧索引栏中的文字, 会根据索引的顺序跳转到左侧对应的位置
* 获取group数组中的每个对象的title值, 并返回到一个NSArray中
[self.groupsvalueForKeyPath:@"title"]
15. 数据刷新
* UITableView通过代理来监听某行被选中的事件。
* 点击某行, 弹出对话框, 然后修改数据, 再把数据刷新到UITableView上。
1> 监听每个cell的点击事件
* 通过代理来监听,
** 选中某行: - (void)tableView:(UITableView*)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
** 取消选中某行: - (void)tableView:(UITableView*)tableView didDeselectRowAtIndexPath:(NSIndexPath *)indexPath
2> 弹出UIAlertView、UIAlertController
* 修来弹出对话框的样式
alertView.alertViewStyle =UIAlertViewStylePlainTextInput;
* 根据索引获取指定的某个文本框
[alertView textFieldAtIndex:0]
[alertView textFieldAtIndex:0].text = hero.name;
* 通过UIAlertView的代理来监听对话框中的按钮的点击事件
* 实现UIAlertView的 - (void)alertView:(UIAlertView*)alertView clickedButtonAtIndex:(NSInteger)buttonIndex代理方法
3> 刷新tableView的方法(刷洗tableView的意思就是重新调用数据源方法和代理方法)
// [self.tableView reloadData]; // 不好,因为重新刷新整个TableView
// [self.tableView reloadRowsAtIndexPaths:@[indexPath]withRowAnimation:UITableViewRowAnimationLeft];
/** 参考代码:
-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath*)indexPath
{
CZHero *hero =self.heros[indexPath.row];
UIAlertView*alertView = [[UIAlertView alloc] initWithTitle:@"提示" message:nil delegate:selfcancelButtonTitle:@"取消" otherButtonTitles:@"确定", nil];
alertView.alertViewStyle = UIAlertViewStylePlainTextInput;
[alertViewtextFieldAtIndex:0].text = hero.name;
// 记录当前点击的行的行号
alertView.tag= indexPath.row;
[alertViewshow];
}
#pragma mark -alertView的代理方法
-(void)alertView:(UIAlertView *)alertViewclickedButtonAtIndex:(NSInteger)buttonIndex
{
// 判断点击的是哪个按钮
if(buttonIndex == 1) {
//获取文本框中的数据
NSString*name = [alertView textFieldAtIndex:0].text;
// 修改模型数据
// 根据行号, 获取当前点击的行的模型数据
CZHero*hero = self.heros[alertView.tag];
hero.name= name;
// 重新刷新TableView数据
// 重新刷新整个TableView, UITableView会重新向datasource请求数据
// 重新调用数据源方法
//[self.tableView reloadData]; // 不好重新刷新整个TableView
// 局部刷新
// 创建一个indexPath对象
NSIndexPath *path = [NSIndexPath indexPathForRow:alertView.taginSection:0];
[self.tableViewreloadRowsAtIndexPaths:@[path] withRowAnimation:UITableViewRowAnimationLeft];
}
}
*/
16. MVC总结:
- MVC是一种设计思想,贯穿于整个iOS开发中,需要积累一定的项目经验,才能深刻体会其中的含义和好处
- MVC中的三个角色
M:Model,模型数据
V:View,视图(界面)
C:Control,控制中心
- MVC的几个明显的特征和体现:
View上面显示什么东西,取决于Model
只要Model数据改了,View的显示状态会跟着更改
Control负责初始化Model,并将Model传递给View去解析展示
17. 剪贴板对象操作
// 获取剪贴板对象
UIPasteboard *pastboard = [UIPasteboardgeneralPasteboard];
/**
剪贴板对象常见的属性:
@property(nullable,nonatomic,copy) NSString*string __TVOS_PROHIBITED;
@property(nullable,nonatomic,copy)NSArray<NSString *> *strings __TVOS_PROHIBITED;
@property(nullable,nonatomic,copy) NSURL *URL__TVOS_PROHIBITED;
@property(nullable,nonatomic,copy)NSArray<NSURL *> *URLs __TVOS_PROHIBITED;
@property(nullable,nonatomic,copy)UIImage *image __TVOS_PROHIBITED;
@property(nullable,nonatomic,copy)NSArray<UIImage *> *images __TVOS_PROHIBITED;
@property(nullable,nonatomic,copy) UIColor*color __TVOS_PROHIBITED;
@property(nullable,nonatomic,copy) NSArray<UIColor*> *colors __TVOS_PROHIBITED;
*/
17. typeof补充
// typeof(指定对象) 是用于获取指定对象的真实类型
// int num = 10;
// typeof(int) num = 10; // == int num = 10;
// typeof (998) num = 5; // == typeof(int) num= 5;