zoukankan      html  css  js  c++  java
  • 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

  • 相关阅读:
    cmd 窗口中运行 Java 程序
    局部变量保证线程安全
    AQS源码详细解读
    理解 Java 内存模型的因果性约束
    高性能Java序列化框架Fse发布
    心跳与超时:高并发高性能的时间轮超时器
    支持内部晋升的无锁并发优先级线程池
    最终一致性:BASE论文笔记
    Activiti架构分析及源码详解
    理解OAuth2
  • 原文地址:https://www.cnblogs.com/ejllen/p/3843395.html
Copyright © 2011-2022 走看看