ios知识点总结——UITableView的展开与收缩及横向Table

UITableVIew是iOS开发中使用最为广泛的一种控件,对于UITableView的基本用法本文不做探讨,本文主要是针对UITableView的展开与收缩进行阐述,在文章的后面也会探讨一下横向table的用法:

1. UITableView的展开与收缩

 下面通过两幅图来了解UITableView的展开与收缩的效果:


这种展开与收缩的原理其实非常简单,在使用该TableVIew的时候需要准备两个自定义的Cell,一个是未展开情况下的Cell,一个是展开后 的Cell,当点击某一行的展开/收缩按钮时,将该行替换为展开/收缩后的Cell,并将其他所有行全部收缩,原理很简单,下面上代码:

(1)扩展UITableView的部分方法:

   创建一个UITableVIew的子类,名称为:ExtensibleTableView

   .h文件中:

@protocol ExtensibleTableViewDelegate <NSObject>

@required

//返回展开之后的cell

- (UITableViewCell *)tableView:(UITableView *)tableView extendedCellForRowAtIndexPath:(NSIndexPath *)indexPath;

//返回展开之后的cell的高度

- (CGFloat)tableView:(UITableView *)tableView extendedHeightForRowAtIndexPath:(NSIndexPath *)indexPath;

@end


@interface ExtensibleTableView : UITableView

{

    //当前被展开的索引

    NSIndexPath *currentIndexPath;

  //  id<ExtensibleTableViewDelegate> delegate_extend;

}

@property(nonatomic,retain)id delegate_extend;

@property(nonatomic,retain)NSIndexPath *currentIndexPath;

//将indexPath对应的row展开

- (void)extendCellAtIndexPath:(NSIndexPath *)indexPath animated:(BOOL)animated goToTop:(BOOL)goToTop;

//将展开的cell收起

- (void)shrinkCellWithAnimated:(BOOL)animated;

//查看传来的索引和当前被选中索引是否相同

- (BOOL)isEqualToSelectedIndexPath:(NSIndexPath *)indexPath;

@end




在.m文件中


@implementation ExtensibleTableView

@synthesize delegate_extend;

@synthesize currentIndexPath;

- (id)init

{

    self.currentIndexPath =nil;

    return [superinit];

}

//重写设置代理的方法,使为UITableView设置代理时,将子类的delegate_extend同样设置

- (void)setDelegate:(id<UITableViewDelegate>)delegate

{

    self.delegate_extend = delegate;

    [super setDelegate:delegate];

}


/*

 将indexPath对应的row展开

 params:

 animated:是否要动画效果

 goToTop:展开后是否让到被展开的cell滚动到顶部

 */


- (void)extendCellAtIndexPath:(NSIndexPath *)indexPath animated:(BOOL)animated goToTop:(BOOL)goToTop

{      

    //被取消选中的行的索引

    NSIndexPath *unselectedIndex = [NSIndexPathindexPathForRow:[self.currentIndexPathrow]inSection:[self.currentIndexPathsection]];

    //要刷新的index的集合

    NSMutableArray *array1 = [[NSMutableArrayalloc]init];

    //若当前index不为空

    if(self.currentIndexPath)

    {

        //被取消选中的行的索引

        [array1 addObject:unselectedIndex];

    }

    //若当前选中的行和入参的选中行不相同,说明用户点击的不是已经展开的cell

    if(![selfisEqualToSelectedIndexPath:indexPath])

    {

        //被选中的行的索引

        [array1 addObject:indexPath];

    }

    //将当前被选中的索引重新赋值

    self.currentIndexPath = indexPath;

    

    if(animated)

    {

        [selfreloadRowsAtIndexPaths:array1withRowAnimation:UITableViewRowAnimationFade];

    }

    else

    {

        [selfreloadRowsAtIndexPaths:array1withRowAnimation:UITableViewRowAnimationNone];

    }

    if(goToTop)

    {

        //tableview滚动到新选中的行的高度

        [selfscrollToRowAtIndexPath:indexPathatScrollPosition:UITableViewScrollPositionTopanimated:YES];

    }

    [array1 release];

}


//将展开的cell收起

- (void)shrinkCellWithAnimated:(BOOL)animated

{

    //要刷新的index的集合

    NSMutableArray *array1 = [[NSMutableArrayalloc]init];

    if(self.currentIndexPath)

    {

        //当前展开的cell的索引

        [array1 addObject:self.currentIndexPath];

        //将当前展开的cell的索引设为空

        self.currentIndexPath =nil;

        [selfreloadRowsAtIndexPaths:array1withRowAnimation:UITableViewRowAnimationFade];    

    }

    [array1 release];

}


//查看传来的索引和当前被选中索引是否相同

- (BOOL)isEqualToSelectedIndexPath:(NSIndexPath *)indexPath

{

    if(self.currentIndexPath)

    {

        return ([self.currentIndexPathrow] == [indexPathrow]) && ([self.currentIndexPathsection] == [indexPathsection]);

    }

    return NO;

}


/*

 

 重写了这个方法,却无效,因为这个方法总在didSelect之前调用,很奇怪。因为无法重写该方法,所以ExtensibleTableView不算完善,因为还有额外的代码需要在heightForRowAtIndexPath和cellForRowAtIndexPath中。哪个找到完善的方法后希望可以与qq82934162联系或者在http://borissun.iteye.com来留言

 

*/


- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath

{

    if([self.currentIndexPathrow] == [indexPathrow])

    {

        return [self.delegate_extendtableView:selfextendedHeightForRowAtIndexPath:indexPath];

    }

    return [superrowHeight];

}


@end

 

这个类时在UITableView的基础上扩展了两个方法,一个是展开情况下的CellForRow方法,一个是在展开情况下的返回heightForRow方法

(2) 准备两个自定义的Cell

   如下图:

          

可以看出这两个Cell上半部分完全一样,主要差别是展开后的Cell多了下面的一部分

(3) 在ViewController中实现该TableVIew的部分方法:

     在ViewController文件中:

  ExtensibleTableView *ccTableView=[[ExtensibleTableViewalloc]initWithFrame:CGRectMake(0,163,ModelSize.width,ModelSize.height-20-44-49-163-40)];

 

    ccTableView.delegate=self;

    ccTableView.dataSource=self;

    ccTableView.delegate_extend=self;     //这个代理就是展开行的代理


下面实现UITableVIew的方法:


 

-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section

{

    return [dataArr count];

}

-(CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath

{

    CGFloat hei=0.0f;

        if([ccTableViewisEqualToSelectedIndexPath:indexPath])

        {

            return [selftableView:ccTableViewextendedHeightForRowAtIndexPath:indexPath];//展开后的行高

        }else

        {

            hei= 50;   // 未展开下的行高

        }

    return hei;

}

-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath

{

        //若当前行被选中,则返回展开的cell

        if([ccTableViewisEqualToSelectedIndexPath:indexPath])

        {

            return [selftableView:ccTableViewextendedCellForRowAtIndexPath:indexPath];

        }

        static NSString *CellIdentifier =@"CCCell";

        UINib *nib = [UINibnibWithNibName:@"CCCell"bundle:nil];

        [tableView registerNib:nib forCellReuseIdentifier:CellIdentifier];

        CCCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];

        if (cell == nil)

        {

            cell = [[[CCCell alloc]

                     initWithStyle:UITableViewCellStyleDefault

                     reuseIdentifier:CellIdentifier]autorelease];

        }

        cell.selectionStyle=UITableViewCellSelectionStyleNone;

       

       //在此设置Cell的相关数据 

       

        UIButton *btn=[[UIButtonalloc]initWithFrame:CGRectMake(ModelSize.width-45,3,45, 45)];

        [btn setImage:[UIImageselfimageNamed:@"tragile_down@2x.png"]forState:UIControlStateNormal];

        btn.tag=indexPath.row;

        [btn addTarget:selfaction:@selector(operateCell:)forControlEvents:UIControlEventTouchUpInside];

        [cell addSubview:btn];

        [btn release];

        return cell;

}

//返回展开之后的cell

- (UITableViewCell *)tableView:(UITableView *)tableView extendedCellForRowAtIndexPath:(NSIndexPath *)indexPath

{

    //每个cell的标识

    NSString *CellTableIdentifier=@"CCopenCell";

    //获得cell

    UINib *nib = [UINibnibWithNibName:@"CCopenCell"bundle:nil];

    [tableView registerNib:nib forCellReuseIdentifier:CellTableIdentifier];

    CCopenCell *cell = [tableView dequeueReusableCellWithIdentifier:CellTableIdentifier];

    if (cell == nil)

    {

        cell = [[[CCopenCell alloc]

                 initWithStyle:UITableViewCellStyleDefault

                 reuseIdentifier:CellTableIdentifier]autorelease];

        cell.frame=CGRectMake(0,0,ModelSize.width ,0);

    }

    cell.selectionStyle=UITableViewCellSelectionStyleNone;


    // 在此设置cell的相关数据

    

    UIButton *btn=[[UIButtonalloc]initWithFrame:CGRectMake(ModelSize.width-45,3,45,45)];

    [btn setImage:[UIImageselfimageNamed:@"tragile_down@2x.png"]forState:UIControlStateNormal];

    btn.tag=indexPath.row;

    [btn addTarget:selfaction:@selector(operateCell:)forControlEvents:UIControlEventTouchUpInside];

    [cell addSubview:btn];

    [btn release];

    return cell;

}

//返回展开之后的cell的高度

- (CGFloat)tableView:(UITableView *)tableView extendedHeightForRowAtIndexPath:(NSIndexPath *)indexPath{

       return 95;

}


OK,以上就是展开与收缩TableVIew的代码,本人已经多次使用,确认无误,如果疑问请联系


最后我们看看横向TableVIew的实现方法:

           _tableView.transform = CGAffineTransformMakeRotation(-M_PI / 2);
           cell.contentView.transform = CGAffineTransformMakeRotation(M_PI / 2); 
方法二:横向UITableView已经有开源实现了  ,EasyTableView,https://github.com/alekseyn/EasyTableView

posted @ 2014-07-14 20:10  ejllen  阅读(794)  评论(0编辑  收藏  举报