单击按钮时将默认 TableViewCell 更改为自定义子类

Posted

技术标签:

【中文标题】单击按钮时将默认 TableViewCell 更改为自定义子类【英文标题】:Changing the default TableViewCell to custom subclass on button click 【发布时间】:2014-07-30 14:43:02 【问题描述】:

在特定行中,我应用带有文本标签和附件按钮的默认 UITableViewCell 类。单击附件按钮时,单元格会展开,我想将 UITableViewCell 更改为我创建的自定义子类。但是,即使单元格被展开,它也不会切换到自定义子类。有什么想法可以解决吗?

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

    CGFloat result;

    switch ([indexPath row])
    

        case 2:
        

            if ([indexPath isEqual:expandedRow]) 
                return 100;

             else 

            return 42;
        


    
    return result;



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

NSString *CellIdentifier;
NSString *CellIdentifierexp;

UITableViewCell *cell;
    if (cell == nil) 
      if (indexPath.row == 2) 

            if ([indexPath isEqual:expandedRow]) 


                cell = [[ExpandedCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifierexp];

else

            cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault  reuseIdentifier:CellIdentifier];
            

switch ([indexPath row])
    
      case 2:
        

            if ([indexPath isEqual:expandedRow]) 

                NSLog(@"bike");

           ExpandedCell *expandedcell = (ExpandedCell *)cell;

                [expandedcell.text setText:self.descr];

                NSArray *indexPathArray=[NSArray arrayWithObject:indexPath];
                [self.tableview reloadRowsAtIndexPaths:indexPathArray withRowAnimation:UITableViewRowAnimationNone];


                    else 

                       cell.textLabel.text = @"Description";
                       cell.accessoryType = UITableViewCellAccessoryDetailDisclosureButton;
                       cell.selectionStyle = UITableViewCellSelectionStyleNone;
                       cell.textLabel.textColor = UIColorFromRGB(0x2d5b3b);

                       // accessory type image

                       UIImage *image = [UIImage imageNamed:@"greenarrow.jpg"]; //or wherever you take your image from

                       UIButton *button = [[UIButton alloc]initWithFrame:CGRectMake(0,0, image.size.width, image.size.height)];

                       [button setBackgroundImage:image forState:UIControlStateNormal];

                       [button addTarget:self action:@selector(accessoryButtonTapped:withEvent:) forControlEvents:UIControlEventTouchDown];

                       button.userInteractionEnabled = YES;
                       cell.accessoryView = button;


                   

            break;

        

return cell;








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

    switch ([indexPath row])
    
        case 2:
            
                 NSLog(@"Detail Disclosure Tapped");

                expandedRow = indexPath;
                [tableview beginUpdates];
                [tableview endUpdates];


            

    


- (void) accessoryButtonTapped: (UIControl *) button withEvent: (UIEvent *) event



    NSIndexPath * indexPath = [self.tableview indexPathForRowAtPoint: [[[event touchesForView: button] anyObject] locationInView: tableview]];

    if ( indexPath == nil )
        return;

    [self.tableview.delegate tableView: self.tableview accessoryButtonTappedForRowWithIndexPath: indexPath];

【问题讨论】:

【参考方案1】:

哇,你在这里做错了什么:

ExpandedCell *expandedcell = (ExpandedCell *)cell;

[expandedcell.text setText:self.descr];

NSArray *indexPathArray=[NSArray arrayWithObject:indexPath];
[self.tableview reloadRowsAtIndexPaths:indexPathArray withRowAnimation:UITableViewRowAnimationNone];

你应该做的略有不同。在点击按钮时,您只需调用[self.tableview reloadRowsAtIndexPaths:indexPathArray withRowAnimation:UITableViewRowAnimationNone];,然后在cellForRowAtIndexPath 中,如果indexPath 匹配,您应该在方法中返回您的子类的自定义单元格。不需要在那里更新 tableView。

需要我说,这对我来说是一个非常奇怪的 switch 语句:

switch ([indexPath row])

    case 2:
        
             NSLog(@"Detail Disclosure Tapped");

            expandedRow = indexPath;
            [tableview beginUpdates];
            [tableview endUpdates];
        

我会这么说:

if (indexPath.row == 2)
      NSLog(@"Detail Disclosure Tapped");

      expandedRow = indexPath;
      [tableview beginUpdates];
      [self.tableview reloadRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationNone];
      [tableview endUpdates];

【讨论】:

投射单元格的代码应该没问题 - 令人困惑,但没问题。因为案例上面的代码确实有一些逻辑来创建不同的单元格类型,然后案例内部的代码在转换之前有相同的检查。【参考方案2】:

运行代码

expandedRow = indexPath;
[tableview beginUpdates];
[tableview endUpdates];

当点击辅助按钮时只会要求表格视图更新行高,它实际上不会为任何行请求新单元格,因此不会发生单元格类型更改(直到您将行滚动到屏幕之外并且然后重新打开)。

因此,您需要实际重新加载选定的行,而不仅仅是开始和结束更新。

【讨论】:

【参考方案3】:

这里...

UITableViewCell *cell;
    if (cell == nil) 

本地变量不会初始化为 nil ,它们以垃圾开始,可能是 nil ,也可能不是。

无论哪种方式,您都可能无法进入分支。

你会想要从表格中取出一个单元格,这取决于它是否是展开的行

UITableViewCell *cell = nil;
if(thisIsAnExpandedRow) 
    cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifierexp];
    if(!cell) 
       cell = [[ExpandedCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifierexp];
    


else 
     cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
    if(!cell) 
       cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault  reuseIdentifier:CellIdentifier];

    

【讨论】:

以上是关于单击按钮时将默认 TableViewCell 更改为自定义子类的主要内容,如果未能解决你的问题,请参考以下文章

如何在不使用标签的情况下更改 tableviewCell 内的图像按钮

如何在单击按钮时将按钮颜色保存到共享首选项?

单击另一个按钮 swift 2.2 更改声音按钮图像

无法单击 iOS 14 中 TableViewCell 内的按钮 [重复]

引导下拉菜单按钮在单击按钮以及单击屏幕时更改

为啥当我单击目标 c 中的按钮时未从 tableViewCell 获取文本字段数据?