您的位置:首页 > 产品设计 > UI/UE

UITableView的简单介绍和功能

2015-06-11 10:37 288 查看
创建表格视图UITableView的时候一并指定表格的样式:
UITableView* tableView = [[UITableView alloc] initWithFrame:self.view.bounds style:UITableViewStylePlain];
// 设置分割线的颜色
tableView.separatorColor = [UIColor blueColor];
// 设置分割线的样式(UITableViewCellSeparatorStyleNone:会将分割线隐藏)
tableView.separatorStyle = UITableViewCellSeparatorStyleNone;
// 设置分割线到屏幕宽度(ios7.0之前没有这个方法,所以应该先判断是否实现这个方法)
if ([tableView respondsToSelector:@selector(separatorInset)]) {
tableView.separatorInset = UIEdgeInsetsZero;
}

ios8之后设置tableCell的分割线到屏幕宽度的方法
-(void)setSeparatorInsetMarginZero
{
self.separatorInset = UIEdgeInsetsZero;
if ([self respondsToSelector:@selector(setLayoutMargins:)]) {
self.layoutMargins = UIEdgeInsetsZero;
}
if ([self respondsToSelector:@selector(setPreservesSuperviewLayoutMargins:)]) {
self.preservesSuperviewLayoutMargins =NO;
}
}

//设置tableView可以在编辑的状态下可以选中
[tableView setAllowSelectionDuringEditing:YES];

//下面的方法可以使tableView直接显示到最下面
NSIndexPath *index = [NSIndexPath indexPathForRow:数组(里面存储的是数组元素).count-1 inSection:第几个分区];
[tableView scrollToRowAtIndexPath:index atScrollPosition:UITableViewScrollPositionBottom animated:YES];

设置头视图:
[tableView.tableHeaderView addSubView:视图对象];
设置tableView的背景视图:
tableView.backgroundView = 视图对象;
设置tableView被选中的背景视图:
tableView.selectedBackgroundView = 视图对象;

自定义tableView的时候,添加到tableView的视图上应用这个方法:
cell上专门用来放置控件的view
[tableView.contentView addSubview:视图对象];

设置表格视图的代理:
注意:应在头文件中添加<UITableViewDelegate,UITableViewDataSource>
tableView.delagate = self;
将self视图控制器设置为tableView的数据源
tableView.dataSource = self;
tableView的刷新方法
[tableView reloadData];

#pragma mark ————以下是代理实现的方法-------

//指定cell的行高,默认是44(一般都写)
-(CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{ return ?;}

//点击某一行触发这个选择方法(一般都写)
-(void) tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath{
……..(自己要写的代码)
//会经常做这样的操作(目的是点进去之后使得选择的这一行不被选择)
[tableView tableView:tableView didDeselectRowAtIndexPath:indexPath];
}

//反选一个cell的时候调用:取消之前选择的cell
//通俗解释:点击另外一行的时候,会先调用之前选择的那一行并取消选择
-(void)tableView:(UITableView *)tableView didDeselectRowAtIndexPath:(NSIndexPath *)indexPath{}

//返回表中有多少个分区
-(NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
return 数组(里面存储的是数组元素).count;
}

//返回某个分区中的行数(必须写)
-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return [[数组(里面存储的是数组元素) objectAtIndex:section] count];
}

/******************************
重中之重
******************************/
/*
复用机制
1.并不是创建了很多个cell的对象,而是使用复用机制,将滑出屏幕的cell放到可重用队列中,供后面使用
2.一个新的cell出现的时候,不是直接创建,再是从可重用队列中去取,如果取不出则创建
3.最多创建的数量是满屏的情况下的cell数量+1
4.利用机制可以用在将来的软件设计上
*/
//indexPath:包含两个值:
//section:第几个分区
//row:第几行
//此方法是每一行在出现屏幕的时候调用
//返回每一个显示cell(必须写)
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
// 定义一个静态字符串变量,作用:用来当做标识
// 注意:不同的布局cell,可重用标识要不同
static NSString * cellId = @"cellId";

// 从当前的tableView的可重用队列中寻找cellId标识的cell,并赋值得到一个cell
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:cellId];

if (!cell) {
// 如果这个cell不存在,则创建一个(记得用autorelease让它自动释放)
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:cellId] autorelease];
}
//若有分区,则应获得对应分区的数组
NSMutableArray* arr = [数组(里面存储的是数组元素) objectAtIndex:indexPath.section];

// 设置cell的主要内容
cell.textLabel.text = [arr objectAtIndex:indexPath.row];

// 设置cell的副标题的内容
cell.detailTextLabel.text =@“……”;

// 设置cell右侧的指示图标
cell.accessoryType = ?;

// 设置tableViewCell的标题图片,这个图片会自动压缩,如果图片过大会压缩后面的文字
cell.imageView.image = [UIImage imageNamed:@“?"];

return cell;
}
//点击了cell右侧的指示图标就会调用该方法
-(void) tableView:(UITableView *)tableView accessoryButtonTappedForRowWithIndexPath:(NSIndexPath *)indexPath{}

//分区的页眉
-(NSString*)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section
{
return 要设置的分区页眉;
}

//分区的页脚
-(NSString *)tableView:(UITableView *)tableView titleForFooterInSection:(NSInteger)section
{
return 要设置的分区页脚;
}

//配合使用系统自带的编辑按钮
self.navigationItem.leftBarButtonItem = self.editButtonItem;
//编辑按钮在改变状态的时候,会调用这个方法
-(void) setEditing:(BOOL)editing animated:(BOOL)animated
{
// 需要先调用父类的方法
[super setEditing:editing animated:animated];
// 让table变成编辑状态
[tableView setEditing:editing];
}

-(UITableViewCellEditingStyle)tableView:(UITableView *)tableView editingStyleForRowAtIndexPath:(NSIndexPath *)indexPath
{
//判断indexPath的两个属性值,然后根据自己的需要对其进行删除或者增加
//注意:只返回一种就仅仅只是删除或者增加 若返回两种(中间加个 | —> 或)则变成多行编辑模式
return UITableViewCellEditingStyleDelete or UITableViewCellEditingStyleInsert;
}

//以下三个是对是否可以编辑操作已经如何操作的实现方法(增加和删除两种操作)

//是否可以编辑cell
-(BOOL)tableView:(UITableView *)tableView canEditRowAtIndexPath:(NSIndexPath *)indexPath
{
return YES;
}

// 实现编辑(删除,增加)的方法
-(void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath
{
// 先判断编辑的风格是删除还是增加

// 若是删除(UITableViewCellEditingStyleDelete)的话应分以下两步:
// A:删除的时候,先删除数据源中的数据
[数组(里面存储的是数组元素) objectAtIndex:indexPath.section] removeObjectAtIndex:indexPath.row];
// B:然后删除table中的行(找到indexPath所在的行,以数组形式返回)
[table deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationFade];

// 若是增加(UITableViewCellEditingStyleInsert)的话应分以下两步:
// A:往数组中增加数据
[[数组(里面存储的是数组元素) objectAtIndex:indexPath.section] insertObject:增加的对象 atIndex:indexPath.row];
// B:刷新当前的table
[tableView reloadData];
}

//设置cell往左滑动的时候出现的删除键里面的文字
-(NSString*)tableView:(UITableView *)tableView titleForDeleteConfirmatio
4000
nButtonForRowAtIndexPath:(NSIndexPath *)indexPath
{
return @"删除";
}

//往table插入某行
- (void)insertRowsAtIndexPaths:(NSArray *)indexPaths withRowAnimation:(UITableViewRowAnimation)animation;
//替换table中的某行
- (void)reloadRowsAtIndexPaths:(NSArray *)indexPaths withRowAnimation:(UITableViewRowAnimation)animation;
//移动table中的某行到另一行
- (void)moveRowAtIndexPath:(NSIndexPath *)indexPath toIndexPath:(NSIndexPath *)newIndexPath;

实现索引(主要新增内容):
成员属性:
定义搜索框对象:
UISearchBar *_searchBar;
定义搜索展示控制器对象:
UISearchDisplayController *_displayController;
定义搜索出来显示在tableView的数据源数组:
NSMutableArray *_searchResultArr;

初始化数组
_searchResultArr = [[NSMutableArray alloc] init];
初始化搜索框(使用默认高度)
_searchBar = [[UISearchBar alloc] initWithFrame:CGRectMake(0, 0, 0, 44)]
再加到tableView的头视图上(即最上面):
_tableView.tableHeaderView = _searchBar;
// _displayController这里面自带了一个tableView,现在在这个视图控制器里面有两个tableView,而这两个tableView的代理和数据源都指向self
// 这里面所有的代理方法都需要对这两个tableView进行分别处理
_displayController = [[UISearchDisplayController alloc] initWithSearchBar:_searchBar contentsController:self];
// 设置自带的tableView的代理和数据源
_displayController.searchResultsDelegate = self;
_displayController.searchResultsDataSource = self;

新增的方法:

//创建索引
//返回是是一个包含字符串的数组
//默认情况下,点击索引中的某一项会跳转到对应下标的分区
-(NSArray *)sectionIndexTitlesForTableView:(UITableView *)tableView{}

//返回一个数字,对应的是tableView中的分区的下标
//index对应的是索引中的下标
-(NSInteger)tableView:(UITableView *)tableView sectionForSectionIndexTitle:(NSString *)title atIndex:(NSInteger)index{}

搜索主要实现应在这里实现(注意:所有代理方法都要判断是否是原来的表格视图在调用):
-(NSInteger) tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
// 开始搜索数据的收集之前,需要先清空搜索结果数组中的所有数据
[_searchResultArr removeAllObjects];
// 在这里面对搜索结果的数据进行收集
// 判断是搜索控制器的tableView调用了这个方法(即不是原来的表格视图在调用这个方法)
if (tableView != _tableView) {
// 获得搜索框中的数据
NSString *str = _searchBar.text;
// 遍历原来的表格视图里的分区数组
for (NSArray *arr in _dataArr) {
// 遍历得到的分区里面的数据
for (NSString *dataStr in arr) {
// 如果数据与搜索框中的数据匹配,则加到_searchResultArr数组中
NSRange rang = [dataStr rangeOfString:str];
// 判断搜索出来的数据是否存在(NSNotFound = NSIntegerMax —>>#define NSIntegerMax LONG_MAX)
if (rang.location != NSNotFound) {
[_searchResultArr addObject:dataStr];
}
}
}
}
return tableView == _tableView ? [[_dataArr objectAtIndex:section]count]:_searchResultArr.count;
}

Xib定制cell
可重用标识符,需要和xib文件中设置一样
static NSString *strId = @"strID";
JTestTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:strId];
if (!cell)
{
// Xib定制的cell
// 参数一:要和xib文件的名字一样
// xib用于cell的定制和将来改动很少的视图
// 参数三返回的是xib里面cell的元素
cell = [[[NSBundle mainBundle] loadNibNamed:@"TestTableViewCell" owner:self options:nil] objectAtIndex:0];
}

itoast效果主要实现下面三个方法:
_tableView是全局变量
-(void)scrollViewWillBeginDecelerating:(UIScrollView *)scrollView
{
_labelView.hidden = NO;
}

-(void)scrollViewDidScroll:(UIScrollView *)scrollView
{
// 拿到_labelView的中心的的坐标,相对于它所在的View
CGPoint p = [_tableView convertPoint:_labelView.center fromView:self.view];
// 获取当_tableView 的titleForHeaderInSection的位置经过p这个点的时候的值
NSIndexPath *index = [_tableView indexPathForRowAtPoint:p];
_labelView.text = [NSString stringWithFormat:@"%c",index.section+'A'];
}

-(void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView
{
_labelView.hidden = YES;
}

懒加载实现:
//慢慢滑动或者快速滑动的时候,手指离开屏幕的瞬间调用的函数
-(void) scrollViewDidEndDragging:(UIScrollView *)scrollView willDecelerate:(BOOL)decelerate
{
if(decelerate == YES)
{
//说明手离开屏幕 但是tableView还在减速 说明这是快速滑动
}else
{
//慢慢滑动 应该加载图片
UITableView *tableView = (UITableView *)scrollView;
[self loadVisibleImages:tableView];//加载图片的函数
}
}

//快速滑动 手停下来
-(void) scrollViewDidEndDecelerating:(UIScrollView *)scrollView
{
[self loadVisibleImages:(UITableView *)scrollView];
}

-(void) loadVisibleImages:(UITableView *)tableView
{
//首先看屏幕到底有哪些cell的indexPath
NSArray *arr = [tableView visibleCells];
//获取tableView当前可见的cell
for (UITableViewCell *cell in arr)
{
NSIndexPath *indexPath = [tableView indexPathForCell:cell];
//取得cell所在的indexPath
//启动下载
}
}

实现索引功能(实现的文件全部内容):

#import "JRootViewController.h"

@interface JRootViewController ()
{
UITableView *_tableView;
NSMutableArray *_dataArr;
NSMutableArray *_indexArr;
// 搜索框
UISearchBar *_searchBar;
// 搜索展示控制器
UISearchDisplayController *_displayController;

NSMutableArray *_searchResultArr;
}
@end

@implementation JRootViewController

- (void)viewDidLoad
{
[superviewDidLoad];
self.title =@"通讯录索引";
[selfparpareData];
[selfuiConfig];

}
-(void) parpareData
{
_dataArr = [[NSMutableArrayalloc] init];
_indexArr = [[NSMutableArrayalloc] init];
_searchResultArr = [[NSMutableArrayalloc] init];
for (int i ='A'; i<='Z'; i++)
{

if (i =='I') {
continue;
}
[_indexArraddObject:[NSStringstringWithFormat:@"%c",i]];
NSMutableArray* arr = [[NSMutableArrayalloc] init];

for (int j =0; j<10; j++)
{
NSString* str = [NSStringstringWithFormat:@"第%c分区第%d行",i,j];
[arr addObject:str ];
}
[_dataArraddObject:arr];
[arr release];
}
}

-(void) uiConfig
{
_tableView = [[UITableViewalloc] initWithFrame:self.view.boundsstyle:UITableViewStylePlain];
[self.viewaddSubview:_tableView];
[_tableViewrelease];
_tableView.delegate =self;
_tableView.dataSource =self;
_searchBar = [[UISearchBaralloc] initWithFrame:CGRectMake(0,0, 0,44)];
_tableView.tableHeaderView =_searchBar;
[_searchBarrelease];
// _displayController这里面自带了一个tableView,现在在这个视图控制器里面有两个tableView,而这两个tableView的代理和数据源都指向self
// 这里面所有的代理方法都需要对这两个tableView进行分别处理
_displayController = [[UISearchDisplayControlleralloc] initWithSearchBar:_searchBarcontentsController:self];
// 设置自带的tableView的代理和数据源
_displayController.searchResultsDelegate =self;
_displayController.searchResultsDataSource =self;
}
#pragma mark -------代理实现---------
-(NSInteger) numberOfSectionsInTableView:(UITableView *)tableView
{
NSLog(@"tableView:%@",tableView);
return tableView ==_tableView?_dataArr.count:1;
}
-(NSInteger) tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
// 开始搜索数据的收集之前,需要先清空结果数组中的所有数据
[_searchResultArrremoveAllObjects];
// 在这里面对搜索结果的数据进行收集
// 是搜索控制器的tableView调用了这个方法
if (tableView !=_tableView) {
NSString *str =_searchBar.text;
for (NSArray *arrin _dataArr) {
for (NSString *dataStrin arr) {
// 如果数据于搜索框中的数据匹配,则加到_searchResultArr数组中
NSRange rang = [dataStrrangeOfString:str];

if (rang.location !=NSNotFound) {
[_searchResultArraddObject:dataStr];
}
}
}
}
return tableView ==_tableView ? [[_dataArrobjectAtIndex:section]count]:_searchResultArr.count;
}
-(UITableViewCell *) tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
staticNSString * cellId = @"cellID";
UITableViewCell *cell = [tableViewdequeueReusableCellWithIdentifier:cellId];
if (!cell) {
cell = [[[UITableViewCellalloc] initWithStyle:UITableViewCellStyleSubtitlereuseIdentifier:cellId] autorelease
];
}
if (tableView ==_tableView) {
cell.textLabel.text = [[_dataArrobjectAtIndex:indexPath.section]objectAtIndex:indexPath.row];
}else
{
//搜索结果的cell
cell.textLabel.text = [_searchResultArrobjectAtIndex:indexPath.row];
}
return cell;
}
-(NSString *) tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section
{
return tableView ==_tableView? [_indexArrobjectAtIndex:section]:@"搜索结果";
}
-(CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
return50;
}
//创建索引
//返回是是一个包含字符串的数组
//默认情况下,点击索引中的某一项会跳转到对应下标的分区
-(NSArray *)sectionIndexTitlesForTableView:(UITableView *)tableView
{
NSMutableArray *indexArr = [[NSMutableArrayalloc] init];
// UITableViewIndexSearch会转换成一个搜索图标
[indexArr addObject:UITableViewIndexSearch];
[indexArr addObjectsFromArray:_indexArr];
[indexArr addObject:@"#"];
return indexArr;
}
//返回一个数字,对应的是tableView中的分区的下标
//index对应的时索引中的下标
-(NSInteger)tableView:(UITableView *)tableView sectionForSectionIndexTitle:(NSString *)title atIndex:(NSInteger)index
{
if (index ==0) {
_tableView.contentOffset =CGPointMake(0, -65);
}
return index-1;
}
- (void)dealloc
{
[_indexArrrelease];
[_searchBarrelease];
[_displayControllerrelease];
[_searchResultArrrelease];
[_dataArrrelease];
[superdealloc];
}
@end
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息