更新UITableView上单元格中的子视图

jdn*_*ada 1 xcode objective-c uitableview ipad

我正在使用Storyboard在iPad 6.0中开发一个应用程序.

我先解释一下我的目标.我正在尝试使用2个UITableViewControllers来实现Master-Detail(类似SplitViewController)的View Controller.

第一个UITableView("Master"),让我们调用这个HeaderTableView,顾名思义,列出Headers为...

...第二个UITableView("Detail"),我们称之为EncodingTableView,它包含一个以编程方式更改的CustomTableViewCell(每个单元格中包含的子视图可能是UITextField,UIButton或UISwitch).

请参阅EncodingTableView.m

- (void)updateEncodingFields:(NSArray *)uiViewList
{
    // Add logic for determining the kind of UIView to display in self.tableView

    // Finally, notify that a change in data has been made (not working)
    [self.tableView reloadData];
}
    - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
        {
            NSString *encodingFieldsTableId = @"encodingFieldsTableId";

            CustomTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:encodingFieldsTableId];

            if (cell == nil) {
                cell = [[CustomTableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:encodingFieldsTableId];
            }
            // Change text in textView property of CustomTableViewCell
            cell.encodingFieldTitle.text = uiViewList.title;
            // added methods for determining what are to be added to [cell.contentView addSubView:]
            // data used here is from the array in updateEncodingFields:

        }
Run Code Online (Sandbox Code Playgroud)

My HeaderTableView.m,包含didSelectRowAtIndexPath以更新EncodingTableView

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
            if (![selectedIndexPath isEqual:indexPath]) {
                selectedIndexPath = indexPath;
                [self updateDataFieldTableViewForIndexPath:indexPath];
            }
        }

    - (void)updateDataFieldTableViewForIndexPath:(NSIndexPath *)indexPath {
        [self.encodingTableView updateEncodingFields:self.uiViewList];
    }
Run Code Online (Sandbox Code Playgroud)


问题 - 数据都可以,但为什么EncodingTableView没有"重绘"字段?我怀疑重复使用细胞与此有关,但我无法弄清楚原因.

结果截图:


HeaderTableView中的初始选择 初步选择

HeaderTableView中的第二个选择 第二选择

我尝试过的:

  • 我一直看到诸如[UITableView setNeedsDisplay],[UITableView reloadData]和[UITableView setNeedsLayout]之类的建议,但它们都没有奏效.
  • 删除tableViewCells的重用工作正常,但这会导致我的CustomTableView.encodingFieldTitle的一部分消失.更不用说如果我放弃重用单元格,这可能会导致性能问题.

限制:我知道一个好主意是使用SplitViewController,但这只是我的应用程序的子部分(因此不是RootViewController).

最后,感谢您阅读这么长的帖子.;)

Pau*_*l.s 5

看起来你最有可能在里面添加子视图tableView:cellForRowAtIndexPath:.

问题是,如果你使用单元格重用,那么并不总是从内部的空白平板开始,tableView:cellForRowAtIndexPath:而是可以给你一个已经配置一次的单元格.这就是你所看到的,一个先前已添加标签的单元格会被传回给你,然后你会在顶部添加更多标签.

有几种方法可以解决这个问题:

  1. (我的首选选项)UITableViewCell使用这些额外的子视图作为属性创建子视图.

  2. 确保电池安装一次只是做
    一个伟大的地方做,这是当你真正创造一个细胞,当一个已经不存在,例如内部if (cell)检查

    if (cell == nil) {
      cell = [[CustomTableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:encodingFieldsTableId];
    
      // add subview's here and give them some way to be referenced later
      // one way of doing it is with the tag property (YUK)
      UILabel *subView = [[UILabel alloc] initWithframe:someFrame];
      subView.tag = 1;
      [cell.contentView addSubview:subView];
    }
    
    UILabel *label = (id)[cell.contentView viewWithTag:1];
    label.text = @"some value";
    
    Run Code Online (Sandbox Code Playgroud)