标签:
1 概述
结构:表头视图(table header view),表脚视图(table footer view),节(section),单元格(cell)
相关类:UITableViewCell UITableViewController UITableViewHeaderFooterView 委托协议和数据源协议
分类:普通表视图:用于动态表
分组表视图:用于静态表,进行界面布局
单元格的组成:图标 标题 拓展视图
样式:拓展视图由枚举类型UITableViewCellAccessoryType定义
单元格样式由枚举UITableViewCellStyle定义
2 简单表视图
必须实现:-tableView:numberOfRowsInSection:表视图显示的时候发出,询问当前节中的行数
-tableView:cellForRowAtIndexPath:单元格显示的时候发出,为单元格提供数据
表视图的创建是在实例化表视图控制器的时候完成的
cell的属性:textLabel detailTextLabel imageView
#pragma mark --UITableViewDataSource 协议方法
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return [self.listTeams count];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{ 代码和interface builder结合的方式实现cell 的可重用机制
cell 的样式和identifier都在属性中设置
static NSString *CellIdentifier = @"CellIdentifier";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier forIndexPath:indexPath];
// UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
// if (cell == nil) {
// cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
// }
NSUInteger row = [indexPath row];获得当前的行数
NSDictionary *rowDict = [self.listTeams objectAtIndex:row];
cell.textLabel.text = [rowDict objectForKey:@"name"];
NSString *imagePath = [rowDict objectForKey:@"image"];
imagePath = [imagePath stringByAppendingString:@".png"];
cell.imageView.image = [UIImage imageNamed:imagePath];
cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;
return cell;
}
3 自定义单元格
准备:选择size class-在故事板自定义单元格-添加约束-创建自定义单元格类-关联到故事板中的cell-在Custom Cell类中为自定义的控件添加输出口
代码:在-tableView:cellForRowAtIndexPath:中为新的cell内部单元添加数据
4 添加搜索栏 UISearchBar UISearchBarDelegate
添加SearchBar:注意不能将SearchBar拖到单元格内部
设置SearchBar属性,定义输出口,设置委托
- (void)viewDidLoad { [super viewDidLoad]; //设置搜索栏委托对象为当前视图控制器 self.searchBar.delegate = self; //设定搜索栏ScopeBar隐藏 self.searchBar.showsScopeBar = NO; [self.searchBar sizeToFit]; NSBundle *bundle = [NSBundle mainBundle]; NSString *plistPath = [bundle pathForResource:@"team" ofType:@"plist"]; //获取属性列表文件中的全部数据 self.listTeams = [[NSArray alloc] initWithContentsOfFile:plistPath]; //初次进入查询所有数据 [self filterContentForSearchText:@"" scope:-1]; }
搜索方法:(一个单纯的工具方法)
NSpredict -prefictWithFormat:构建搜索条件
-filterArrayUsingPredict:过滤结果
- (void)filterContentForSearchText:(NSString*)searchText scope:(NSUInteger)scope;
{
if([searchText length]==0)
{
//查询所有
self.listFilterTeams = [NSMutableArray arrayWithArray:self.listTeams];
return;
}
NSPredicate *scopePredicate;
NSArray *tempArray ;
switch (scope) {
case 0: //英文 image字段保存英文名 SELF代表要查询的对象 SELF.image代表要查询的对象的image字段contains[c]代表不区分大小写
scopePredicate = [NSPredicate predicateWithFormat:@"SELF.image contains[c] %@",searchText];
tempArray =[self.listTeams filteredArrayUsingPredicate:scopePredicate];
self.listFilterTeams = [NSMutableArray arrayWithArray:tempArray];
break;
case 1: //中文 name字段是中文名
scopePredicate = [NSPredicate predicateWithFormat:@"SELF.name contains[c] %@",searchText];
tempArray =[self.listTeams filteredArrayUsingPredicate:scopePredicate];
self.listFilterTeams = [NSMutableArray arrayWithArray:tempArray];
break;
default:
//查询所有
self.listFilterTeams = [NSMutableArray arrayWithArray:self.listTeams];
break;
}
}
***************
关于NSPredict的概念http://blog.csdn.net/ztp800201/article/details/8116081
正则表达式https://msdn.microsoft.com/zh-cn/library/ae5bf541(VS.80).aspx
***************
实现代理方法:
- (void)searchBar:(UISearchBar *)searchBar textDidChange:(NSString *)searchText
属性:searchBar.text searchBar.selectedScopeButtonIndex
#pragma mark --UISearchBarDelegate 协议方法
// 获得焦点,成为第一响应者
- (BOOL)searchBarShouldBeginEditing:(UISearchBar *)searchBar
{
self.searchBar.showsScopeBar = TRUE;
[self.searchBar sizeToFit];
return YES;
}
//点击键盘上的搜索按钮
- (void)searchBarSearchButtonClicked:(UISearchBar *)searchBar
{
self.searchBar.showsScopeBar = NO;
[self.searchBar sizeToFit];
[self.searchBar resignFirstResponder];
}
//点击搜索栏取消按钮
- (void)searchBarCancelButtonClicked:(UISearchBar *)searchBar
{
//查询所有
[self filterContentForSearchText:self.searchBar.text scope:-1];
self.searchBar.showsScopeBar = NO;
[self.searchBar sizeToFit];
[self.searchBar resignFirstResponder];
}
//当文本内容发生改变时候调用
- (void)searchBar:(UISearchBar *)searchBar textDidChange:(NSString *)searchText
{
[self filterContentForSearchText:self.searchBar.text scope:self.searchBar.selectedScopeButtonIndex];
[self.tableView reloadData];
}
//当搜索范围选择发生变化时候调用
- (void)searchBar:(UISearchBar *)searchBar selectedScopeButtonIndexDidChange:(NSInteger)selectedScope搜索范围栏中的按钮索引
{
[self filterContentForSearchText:self.searchBar.text scope:selectedScope];
[self.tableView reloadData];
}
4 分节表视图
分节是添加索引和分组的前提
-numberOfSectionInTableView:
-tableView:titleForHeader/FooterInSection:
1)添加索引 一般不再使用拓展视图
排序:sortedArrayUsingSelector:
- (void)viewDidLoad
{
[super viewDidLoad];
NSBundle *bundle = [NSBundle mainBundle];
NSString *plistPath = [bundle pathForResource:@"team_dictionary"
ofType:@"plist"];
//获取属性列表文件中的全部数据
self.dictData = [[NSDictionary alloc] initWithContentsOfFile:plistPath];
NSArray* tempList = [self.dictData allKeys];
//对key进行排序
self.listGroupname = [tempList sortedArrayUsingSelector:@selector(compare:)];
}
实现委托:
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
return [self.listGroupname count];
}
- (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section
{
NSString *groupName = [self.listGroupname objectAtIndex:section];
return groupName;
}
添加索引:-sectionIndexTitlesForTableView:
-(NSArray *) sectionIndexTitlesForTableView: (UITableView *) tableView
{
NSMutableArray *listTitles = [[NSMutableArray alloc] initWithCapacity:[self.listGroupname count]];
//把 A组 -> A
for (NSString *item in self.listGroupname) {
NSString *title = [item substringToIndex:1];
[listTitles addObject:title];
}
return listTitles;
}
2)静态表与控制界面布局
准备:在TableView的属性检查器将Content设为Static Cells,设置Section数,Style设为Grouped
拖拽控件到Cell里
代码:viewController中编辑
在静态表中无需实现数据源和委托协议方法
5 修改单元格
1)删除与插入
-setEditing:animated:设定视图能否进入编辑状态
-tableView:editingStyleForRowAtIndexPath:进行单元格编辑图标的设置
-tableView:commitEditingStyle:forRowAtIndexPath:实现删除或插入的处理
-reloadData 刷新数据
插入单元格时,应该有个控件能接受用户输入的信息:先在Root View Controller Sence中添加TextFiled,为其添加输出口,之后会利用cell.contentView.addSubview来实现添加。
- (void)viewDidLoad
{
[super viewDidLoad];
//设置导航栏
编辑按钮样式的切换取决于当前视图的编辑状态,点击按钮会调用setEditing:animated:方法
self.navigationItem.rightBarButtonItem = self.editButtonItem;
self.navigationItem.title = @"单元格插入和删除";
//设置单元格文本框
self.txtField.hidden = YES;
self.txtField.delegate = self;
声明是可变数组方便对其进行删除或修改
self.listTeams = [[NSMutableArray alloc] initWithObjects:@"黑龙江", @"吉林", @"辽宁", nil];
}
点击按钮回调:确认视图能不能进入编辑状态
#pragma mark -- UIViewController生命周期方法,用于响应视图编辑状态变化
- (void)setEditing:(BOOL)editing animated:(BOOL)animated {
[super setEditing:editing animated:animated];
点击按钮tableView处于编辑状态,textFiela显示出来
[self.tableView setEditing:editing animated:YES];
if (editing) {
self.txtField.hidden = NO;
} else {
self.txtField.hidden = YES;
}
}
实现委托协议:
为插入准备一个空单元格:
#pragma mark --UITableViewDataSource 协议方法
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return [self.listTeams count] + 1;
}
单元格数据要分为两种情况:普通单元格和要插入的那个单元格,在插入的那个中添加文本框
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = @"Cell";
row是从0开始的count是array中元素数量,所以相等的那个就是要编辑的那个,这里的逻辑用YES和NO来表示比较好
BOOL b_addCell = (indexPath.row == self.listTeams.count);
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault
reuseIdentifier:CellIdentifier] ;
}
if (!b_addCell) {
cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;
cell.textLabel.text = [self.listTeams objectAtIndex:indexPath.row];
} else {
self.txtField.frame = CGRectMake(10,0,300,44);
self.txtField.borderStyle = UITextBorderStyleNone;
self.txtField.placeholder = @"Add...";
self.txtField.text = @"";
[cell.contentView addSubview:self.txtField];
}
return cell;
}
实现三步走之后两步:
设定编辑图标:
#pragma mark --UITableViewDelegate 协议方法
- (UITableViewCellEditingStyle)tableView:(UITableView *)tableView
editingStyleForRowAtIndexPath:(NSIndexPath *)indexPath
{
if (indexPath.row == [self.listTeams count]) {
return UITableViewCellEditingStyleInsert;
} else {
return UITableViewCellEditingStyleDelete;
}
}
编辑单元格显示暗淡
- (BOOL)tableView:(UITableView *)tableView shouldHighlightRowAtIndexPath:(NSIndexPath *)indexPath
{
if (indexPath.row == [self.listTeams count]) {
return NO;
} else {
return YES;
}
}
确认编辑样式实现编辑:
-removeObiectAtIndex:
-delegateRowsAtIndexPaths:withRowAnimation:
-insertRowsAtIndexPaths:withRowAnimation:
- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle
forRowAtIndexPath:(NSIndexPath *)indexPath
{
NSArray* indexPaths = [NSArray arrayWithObject:indexPath];
编辑的实质是在数据来源(数据库)中实现删除与插入
if (editingStyle == UITableViewCellEditingStyleDelete)
{
[self.listTeams removeObjectAtIndex: indexPath.row];
[self.tableView deleteRowsAtIndexPaths:indexPaths
withRowAnimation:UITableViewRowAnimationFade];
} else if (editingStyle == UITableViewCellEditingStyleInsert) {
[self.listTeams insertObject:self.txtField.text atIndex:[self.listTeams count]];
[self.tableView insertRowsAtIndexPaths:indexPaths
withRowAnimation:UITableViewRowAnimationFade];
}刷新数据
[self.tableView reloadData];
}
2)移动单元格:单元格重新排序
-setEditing:animated:
-tableView:editing
-tableView:canMoveRowAtIndexPath:
-tableView:moveRowAtIndexPath:
标签:
原文地址:http://www.cnblogs.com/haugezi/p/4818922.html