【问题标题】:Changing the default TableViewCell to custom subclass on button click单击按钮时将默认 TableViewCell 更改为自定义子类
【发布时间】: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];
}

【问题讨论】:

    标签: uitableview uibutton uilabel


    【解决方案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];
      
          }
      }
      

      【讨论】:

        猜你喜欢
        • 2018-11-12
        • 2018-11-22
        • 2018-07-20
        • 2017-06-14
        • 2021-10-04
        • 2017-12-30
        • 1970-01-01
        • 2019-12-09
        • 2015-08-31
        相关资源
        最近更新 更多