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

  • 相关阅读:
    ThinkPHP 3.2.2 实现持久登录 ( 记住我 )
    Java实现 LeetCode 20 有效的括号
    Java实现 LeetCode 20 有效的括号
    Java实现 LeetCode 19删除链表的倒数第N个节点
    Java实现 LeetCode 19删除链表的倒数第N个节点
    Java实现 LeetCode 19删除链表的倒数第N个节点
    Java实现 LeetCode 18 四数之和
    Java实现 LeetCode 18 四数之和
    Java实现 LeetCode 18 四数之和
    Java实现 LeetCode 17 电话号码的字母组合
  • 原文地址:https://www.cnblogs.com/ejllen/p/3843395.html
Copyright © 2011-2022 走看看