UITableView的简单介绍和功能

创建表格视图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 titleForDeleteConfirmationButtonForRowAtIndexPath:(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


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值