将子视图添加到 cell.contentView


- (UITableViewCell *)cellForInfoWithCellIdentifier:(NSString *)cellIdentifier
                                      forIndexPath:(NSIndexPath *)indexPath
                                       inTableView:(UITableView *) tableView
{
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:cellIdentifier forIndexPath:indexPath];
    if (cell == nil)
    {
        cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:cellIdentifier];
    }
    NSLog(@"%d", cell.contentView.subviews.count);
    if (cell.contentView.subviews.count > 0)
    {
        [cell.contentView.subviews[0] removeFromSuperview];
    }
    [cell.contentView addSubview:self.viewsForOptions[self.selectedIndex]];
    NSLog(@"%d", cell.contentView.subviews.count);
    return cell;
}

上面的代码是为cellForRowAtIndexPath中的某个部分和行调用的。每当分段控制对象的值发生更改时,此单元格都会更改。

方法如下:

- (void)testOptionsValueChanged:(id)sender
{
    NSIndexPath *indexPath = [NSIndexPath indexPathForRow:0 inSection:1];
    [self.tableView reloadRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationAutomatic];
}

我只有两个单元格; 每个部分 1 个,因此cell == nil条件始终false

问题:

当表视图加载控制台日志时:

0
1

当我更改分段控件的值时,我仍然得到:

0
1

经过几次尝试,我基本上增加了第二个视图(对于第二个索引)的高度。我似乎不知道为什么会发生这种情况。

编辑:

其他代码段:

- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
    if (indexPath.section == 0)
    {
        // test detail view is a constant height
        if (indexPath.row == 0)
            return 180.0;
    }
    else if (indexPath.section == 1)
    {
        // based on the view loaded from the viewForOptions array
        if (indexPath.row == 0)
        {
            return ((UIView *)self.viewsForOptions[self.selectedIndex]).frame.size.height;
        }
    }
    return 0;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    static NSString *DetailCellIdentifier = @"DetailCell";
    static NSString *InfoCellIdentifier = @"InfoCell";
    UITableViewCell *cell;
    if (indexPath.section == 0)
    {
        // displays views and test button
        if (indexPath.row == 0)
        {
            cell = [self cellForTestDetailWithCellIdentifier:DetailCellIdentifier forIndexPath:indexPath inTableView:tableView];
        }
    }
    else if (indexPath.section == 1)
    {
        // display the view for information based on segmented control
        if (indexPath.row == 0)
        {
            cell = [self cellForInfoWithCellIdentifier:InfoCellIdentifier forIndexPath:indexPath inTableView:tableView];
        }
    }
    cell.selectionStyle = UITableViewCellSelectionStyleNone;
    return cell;
}
- (void)viewDidLoad
{
    // set the selected index for the options segmented control
    self.selectedIndex = 0;
    // instantiate all the views for test segmented control options
    self.aViewController = [[AViewController alloc] ...];
    self.bViewController = [[BViewController alloc] ...];
    self.cViewController = [[CViewController alloc] ...];
    // add all the views to an array that will be used by the tableview
    self.viewsForOptions = @[self.aViewController, self.bViewController, self.cViewController];
}

1,1 0,1是由表视图重用机制引起的。基本上,该表不会重复使用任何已在使用的单元格。因此,当您首次填充并首次刷新表时,将创建新单元格。之后,重用队列中有足够的单元格未被使用,因此不需要创建新的单元格(滚动可能会创建更多单元格)。

您的身高问题可能是由自动调整大小/布局引起的。添加子视图时,应指定它的大小,以及随着超级视图(单元格)大小的更改,应如何更改该大小。并且单元格大小已更改(在添加子视图时记录它)。


单元格的高度是一部分。 通常您需要设置:

UIView *subview = self.viewsForOptions[self.selectedIndex];
subview.frame = cell.contentView.bounds;
[cell.contentView addSubview:subview];

这样,当调整单元格大小时,子视图将具有正确的大小。但这取决于您的自动调整大小规则。如果设置布局约束以固定高度和宽度,则无需设置框架。

无论哪种情况,您都需要指定当超级视图帧更改时子视图帧会发生什么情况。


我想,您的问题是单元格在重复使用之前已调整大小,并且您的子视图仍然附加。因此,它也会被调整大小。然后,在heightForRowAtIndexPath:中使用子视图的高度(现在无效,请尝试记录它)来设置行的高度。

我会考虑更改heightForRowAtIndexPath:的实现,以使用基于所选段而不是子视图帧高度的配置。

最新更新