单击另一个单元格时将 UITableViewCell 折叠到原始大小

Posted

技术标签:

【中文标题】单击另一个单元格时将 UITableViewCell 折叠到原始大小【英文标题】:Collapse UITableViewCell to original size when another cell is clicked 【发布时间】:2013-09-17 15:00:25 【问题描述】:

此问题与以下问题有关:Can you animate a height change on a UITableViewCell when selected?

我正在使用以下代码为该问题中解释的 UITableViewCell 的高度变化设置动画:

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


    ProductCell *cell = (ProductCell *) [tableView cellForRowAtIndexPath:indexPath];

    // Deselect cell
    [tableView deselectRowAtIndexPath:indexPath animated:NO];

    // Toggle 'selected' state
    BOOL isSelected = ![self cellIsSelected:indexPath];


    // Store cell 'selected' state keyed on indexPath
    NSNumber *selectedIndex = [NSNumber numberWithBool:isSelected];
    [self.selectedIndexes setObject:selectedIndex forKey:indexPath];


    if (isSelected) 

        cell.addButton.hidden = NO;

    else 


        cell.addButton.hidden = YES;

   

    // This is where magic happens...
    [self.theMenuListTableView beginUpdates];

    [self.theMenuListTableView endUpdates];



- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath 
    // If our cell is selected, return double height
    if([self cellIsSelected:indexPath]) 
        return kCellHeight * 2.0;
    

    // Cell isn't selected so return single height
    return kCellHeight;


- (BOOL)cellIsSelected:(NSIndexPath *)indexPath 

    NSNumber *selectedIndex = [self.selectedIndexes objectForKey:indexPath];
    return selectedIndex == nil ? FALSE : [selectedIndex boolValue];

这工作正常,但我想要的是,当单击一个单元格并且高度已设置动画,然后我单击另一个单元格时,我希望第一个单元格收缩/折叠到它的原始大小和其他展开(动画高度变化)。 我怎样才能做到这一点?

【问题讨论】:

【参考方案1】:

当您选择一个单元格并且它已动画化时,存储该单元格的 indexPath。当您单击另一个单元格时,请检查它是同一个单元格还是 indexPath 不同。编写一个方法来制作其他动画。如果您有一个存储的 indexPath,则为具有该存储 indexPath 的单元格调用该新方法。希望对你有帮助。

【讨论】:

【参考方案2】:

所以我猜您将选定的索引保存在 NSDictionary 对象中,并且为每个 indexPath 保存状态(已选择/未选择)。 您需要做的是只保存 1 个单元格的索引,即选中的那个。

所以,基本上需要以下改动:

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


ProductCell *cell = (ProductCell *) [tableView cellForRowAtIndexPath:indexPath];

// Deselect cell
[tableView deselectRowAtIndexPath:indexPath animated:NO];

if (![indexPath isEqual:selectedIndex]) 

    cell.addButton.hidden = NO;

   // Store cell 'selected' state keyed on indexPath
   selectedIndex = indexPath;

else 
    //Click deselecting cell
    selectedIndex = nil;

    cell.addButton.hidden = YES;

  

// This is where magic happens...
[self.theMenuListTableView beginUpdates];

[self.theMenuListTableView endUpdates];

   

- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath 
    // If our cell is selected, return double height
    if(selectedIndex != nil && [selectedIndex isEqual:indexPath]) 
        return kCellHeight * 2.0;
    

    // Cell isn't selected so return single height
    return kCellHeight;


//- (BOOL)cellIsSelected:(NSIndexPath *)indexPath 
//
//    NSNumber *selectedIndex = [self.selectedIndexes objectForKey:indexPath];
//    return selectedIndex == nil ? FALSE : [selectedIndex boolValue];
//

并添加到控制器的 .h 文件中

@property NSIndexPath * selectedIndex;

到.m

@synthetize selectedIndex;

我可以检查这段代码是否运行,所以试试看它是否适合你。

【讨论】:

【参考方案3】:

也许有帮助:

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

    static NSString *CellIdentifier = @"Cell";

    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];

    if (cell == nil) 
        cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault
                                   reuseIdentifier:CellIdentifier] autorelease];
    

    cell.textLabel.text = [NSString stringWithFormat:@"%d",indexPath.row];
    cell.selectionStyle = UITableViewCellEditingStyleNone;
    return cell;


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

    return 3;


- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath 
    [tableView reloadRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationMiddle];

    if (indexPath.row > 0) 
        NSIndexPath *path = [NSIndexPath indexPathForRow:indexPath.row - 1 inSection:indexPath.section];
        [tableView reloadRowsAtIndexPaths:@[path] withRowAnimation:UITableViewRowAnimationNone];
    


- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath 
    // If our cell is selected, return double height
    if([self cellIsSelected:indexPath]) 
        return 40 * 2.0;
    

    // Cell isn't selected so return single height
    return 40;


- (BOOL)cellIsSelected:(NSIndexPath *)indexPath 
    return (tblView.indexPathForSelectedRow.row == indexPath.row);

【讨论】:

这个解决方案真的很好,因为它更简单.. 但是在 ios 7 下,这会导致分隔线消失。

以上是关于单击另一个单元格时将 UITableViewCell 折叠到原始大小的主要内容,如果未能解决你的问题,请参考以下文章

单击表格单元格时将变量值发送到下一个视图控制器

单击collectionview的单元格时打开另一个视图控制器

当我单击 tableview 单元格时,UITextfield 没有显示文本?

如何在集合视图中单击单元格时创建按钮操作

为啥在制作自定义表格视图单元格时将可重用单元格出列两次

按下表格单元格时将视图加载到导航视图控制器中