你的位置:首页 > 操作系统

[操作系统]UITableView点击每个Cell,Cell的子内容的收放


关于点击TableviewCell的子内容收放问题,拿到它的第一个思路就是,

方法一:

运用UITableview本身的代理来处理相应的展开收起:

1.代理:- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath

2. 需要声明一个全局BOOL变量isOpen,记录当前cell的状态(展开/收起),声明一个NSInterge类型selectedIndexRow,记录选择的cell的row,切记初始化相应的属性。

(ps:在网上看到很多文章都是这样,但是真的用的时候,发现,我们需要另外声明一个NSIndexPath类型的selectedIndex,或者用到时候自己运用记录的row生成也可,也许确实是我自己多此一举)

3.首先,我们需要理清自己需求的逻辑关系,什么时候展开/收起,展开收起时它的高度,个数等等有什么变化------->来进行代理,数据源方法的书写

下面也是展示tableview时的调用顺序

  1>://返回cell个数
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
  2>://返回每行的高度
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
  3>://请求数据元代理为tableView插入需要的cell
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
  4>://监听点击的cell
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath

代码:

#pragma mark ---------  UITableViewDelegate && UITableViewDataSource -----

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

{

    return self.scoreDataArray.count;//根据自己的具体需要返回

}

//计算高度---根据需求,动态计算内容的高度

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

{

    //indexPath.row == selectedIndex.row &&

    NSLog(@"heightForRow   %ld",(long)selectedIndex.row);

    if (indexPath.row == selectedIndex.row && selectedIndex != nil)

    {

        if (isOpen == YES)

        {

//内部内容直接忽略即可

            YunGangScoreData *data = [[YunGangScoreData alloc] init];

            //data = self.scoreDataArray[indexPath.row];

            data = self.scoreDataArray[selectedIndex.row];

            if (data.detailTypeArray.count>0)

            {

                self.cellHeight = 60+data.detailTypeArray.count*40;

                return self.cellHeight;

            }

            return 60;

        }

        else

        {

            return 60;

        }

    }

    return 60;

}

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

{

    //indexPath.row == selectedIndex.row &&

    NSLog(@"cellForRow   %ld",(long)selectedIndex.row);

    if (indexPath.row == selectedIndex.row && selectedIndex != nil)

    {//内部内容直接忽略即可

        //如果是展开

       if (isOpen == YES)

        {

            YunGangScoreTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"YunGangScoreTableViewCell"];

            cell.selectionStyle = UITableViewCellSelectionStyleNone;

            cell.data = self.scoreDataArray[selectedIndex.row];

            cell.isOpen = YES;

            return cell;

        }

        else

        {//收起

            YunGangScoreTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"YunGangScoreTableViewCell"];

            cell.selectionStyle = UITableViewCellSelectionStyleNone;

            cell.data = self.scoreDataArray[selectedIndex.row];

            cell.isOpen = NO;

            return cell;

        }

    }

    else//不是自身

    {

        YunGangScoreTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"YunGangScoreTableViewCell"];

        cell.selectionStyle = UITableViewCellSelectionStyleNone;

        cell.data = self.scoreDataArray[indexPath.row];

        cell.isOpen = NO;

        return cell;

    }

}

-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath

{

//将索引加到数组中

    NSArray *indexPaths = [NSArray arrayWithObject:indexPath];

    //判断选中不同row状态时候

     //我自己加上的,看好多文章没有,可能我错了,selectedIndex = indexPath;

    NSLog(@"%ld",(long)selectedIndex.row);

    if (selectedIndex != nil && indexPath.row == selectedIndex.row)

    {//将选中的和所有索引都加进数组中

       // indexPaths = [NSArray arrayWithObjects:indexPath,selectedIndex, nil];

        isOpen = !isOpen;

    }

    else if (selectedIndex != nil && indexPath.row != selectedIndex.row)

   {

       indexPaths = [NSArray arrayWithObjects:indexPath, selectedIndex,nil];

        isOpen = YES;

    }

    //记下选中的索引

    selectedIndex = indexPath;

    //刷新

    [tableView reloadRowsAtIndexPaths:indexPaths withRowAnimation:UITableViewRowAnimationFade];

 }

大致运用的就这些内容,自己看着调试下。。。

方法二: 我试了上面方法,发现可能出现刷新等问题,也就换了下面的

这里用section当做第一个cell,然后加载view到section上,添加手势来作为点击事件,展开的内容加载cell(第二个)

直接上代码:


1.声明属性:

    //cell收放,以及记录cell的selectedIndex

    NSMutableDictionary *_showDic;//用来判断分组展开与收缩的

    int index;

2.用section的个数来展示未点击时的tableview内容

3计算点击每个section之后展开的cell的个数

4.这里自己根据需求,以及返回的内容来计算点开后的cell应该拥有的高度

5.加载点击之后的cell内容,同时传递点击的那个section的数据信息

6.根据需要计算每一个section需要的高度(我这里最后一个有需要)

7.加载每个section的内容,需要注意,这里加载的view继承

UITableViewHeaderFooterView  

-(UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section

{

    NSArray* objs = [[NSBundle mainBundle] loadNibNamed:@"YunGangScoreTableViewCell" owner:nil options:nil];

    YunGangScoreTableViewCell* cell = [objs objectAtIndex: 0];

    if (self.scoreDataArray.count>0)

    {//确保有数据

        YunGangScoreData *data = self.scoreDataArray[section];

        cell.data = data;

    }

    // 单击的 Recognizer ,收缩分组cell

    cell.tag = section;

    UITapGestureRecognizer *singleRecognizer = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(SingleTap1:)];

    singleRecognizer.numberOfTapsRequired = 1; //点击的次数 =1:单击

    [singleRecognizer setNumberOfTouchesRequired:1];//1个手指操作

    [cell addGestureRecognizer:singleRecognizer];//添加一个手势监测;

    

    return cell;

}

同时,为了适配问题,我们需要在自定义的view中改变这个view的frame

8.点击手势的事件以及处理

 

9,需要注意的是,每次请求数据,刷新tableview的时候,需要清空_showDic

其他的内容,就自己根据需要添加修改就可以了,两种方法经过测试,第一种展示都没问题,刷新之后貌似存在混乱,如果需要使用就要好好修改下,第二种方法,测试可以使用,不存在什么大问题,满足需求,下面把效果图贴上: