【问题标题】:View changing on UITableView updateUITableView 更新时的视图变化
【发布时间】:2014-02-25 13:17:40
【问题描述】:

我在UITableView 中有一个相当复杂的表格。此表单在表格视图单元格中有一些UICollectionView,还有一些选择器,它们的显示方式与日历应用程序相同:

现在,当我在我的应用程序上执行此操作时,我的 UICollectionView 之一变得比它开始时更高 - 而且它一直在继续(我添加了一个红色边框以确保它是正在调整大小的 UICollectionView ):

我尝试调试 UICollectionView 视图属性,但它从未改变(它的 getter/setter 调用次数没有超出我的预期) - 即使我在 cellForRowAtIndexPath 上打印它时它确实显示已调整大小。有什么办法可以更好地调试这个问题,或者有人遇到过同样的情况吗?

谢谢!

代码:

    - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
//self.campos is a dictionary with sections and rows stored
    NSMutableArray *infoCampos = [[self.campos objectAtIndex:indexPath.section] objectForKey:@"campos"];
NSDictionary *infoCampo = [infoCampos objectAtIndex:indexPath.row];

if ([[infoCampo objectForKey:@"nome"] isEqualToString:@"dosePorComprimido"]) {
    //Remove picker cell if finds it
    for (infoCampo in infoCampos) {
        if ([infoCampo objectForKey:@"view"] == self.dosagemMedicamento.view) {
            [infoCampos removeObject:infoCampo];
            [tableView reloadSections:[NSIndexSet indexSetWithIndex:indexPath.section] withRowAnimation:UITableViewRowAnimationAutomatic];
            [tableView deselectRowAtIndexPath:indexPath animated:YES];
            return;
        }
    }

    //Insert new cell
    infoCampo = [infoCampos objectAtIndex:indexPath.row];
    [infoCampos addObject:@{@"tipo":@5, @"view":self.dosagemMedicamento.view, @"nome":[infoCampo objectForKey:@"nome"]}];
    [tableView reloadSections:[NSIndexSet indexSetWithIndex:indexPath.section] withRowAnimation:UITableViewRowAnimationAutomatic];
    [self.dosagemMedicamento.view.superview addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"|[pickerDosagem]|" options:0 metrics:nil views:@{@"pickerDosagem":self.dosagemMedicamento.view}]];
}
}

- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
    NSDictionary *infoCampo = [[[self.campos objectAtIndex:indexPath.section] objectForKey:@"campos"] objectAtIndex:indexPath.row];
    UIView *view;

    if ([infoCampo objectForKey:@"view"]) {
        view = (UIView *) [infoCampo objectForKey:@"view"];
        return view.frame.size.height;
    }

    return 44.0f;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:

(NSIndexPath *)indexPath
{
    UITableViewCell *cell;
    NSMutableDictionary *infoCampo = [[[self.campos objectAtIndex:indexPath.section] objectForKey:@"campos"] objectAtIndex:indexPath.row];
    UIView *view;

cell = [tableView dequeueReusableCellWithIdentifier:[[infoCampo objectForKey:@"nome"] stringByAppendingString:@"ViewLinhaCellView"] forIndexPath:indexPath];

        view = [cell viewWithTag:1];

        [view addSubview:[infoCampo objectForKey:@"view"]];

return cell;
}

编辑: 忘了提到我没有使用 reloadData 更新表格视图,而是仅使用 reloadRowsAtIndexPaths 和 reloadSections 更新所需的部分/行。这让它变得更加奇怪,因为我没有重新加载那个特定的部分。

编辑 2: 添加数据源和委托代码

【问题讨论】:

  • 发布您的表格视图数据源代码。它似乎是你返回那个单元格的错误高度。检查您的 heightforcell 方法并确保您为该单元格返回正确的值
  • 我知道 - 我的 heighForRowAtIndexPath 只返回子视图高度,所以问题是这个子视图(UICollectionView)正在调整大小,单元格也是如此。
  • 你能贴出代码吗?如果没有代码示例,将很难说出问题所在。
  • @Austin 具体是哪个方法?此屏幕中涉及很多类,因此很难将所有内容粘贴到那里。
  • 我认为表格视图数据源/委托代码最相关

标签: ios uitableview uicollectionview uipickerview


【解决方案1】:

我相信你的问题就在这里,在tableView:heightForRowAtIndexPath:的实现中

- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
    NSDictionary *infoCampo = [[[self.campos objectAtIndex:indexPath.section] objectForKey:@"campos"] objectAtIndex:indexPath.row];
    UIView *view;

    if ([infoCampo objectForKey:@"view"]) {
        view = (UIView *) [infoCampo objectForKey:@"view"];
        return view.frame.size.height;
    }

    return 44.0f;
}

视图可能正在通过自动布局或其自动调整大小掩码调整大小。这里没有足够的信息来说明原因,但是表格视图和自动布局可能会有一些有趣的行为。我建议只返回您设置的高度,而不是从视图中获取高度:

- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
    NSDictionary *infoCampo = [[[self.campos objectAtIndex:indexPath.section] objectForKey:@"campos"] objectAtIndex:indexPath.row];
    UIView *view;

    if ([infoCampo objectForKey:@"view"]) {
        if ([infoCampo objectForKey:@"viewHeight"]) {
            return [[infoCampo objectForKey:@"viewHeight"] floatValue];
        } else {
            return 216.0f;
        }
    }

    return 44.0f;
}

viewHeight 键允许您为每个单元格的视图指定自定义高度,但此实现还返回一个默认高度 (216),它恰好是选取器视图的标准高度。

【讨论】:

  • 好主意,奥斯汀。我想我可能会同意,即使我很想知道调整大小的原因。谢谢!
  • 只是建议检查一下,如果视图是从笔尖加载的:当您创建笔尖时,即使笔尖使用自动布局,视图也会设置自动调整大小的掩码。尝试将视图的autoresizingMask 属性设置为UIViewAutoresizingNone
  • 即使我不是从笔尖加载它,设置该属性也解决了!你摇滚!但是您能否详细说明 autoresizingMask 的工作原理?为什么会受到 UITableView 重载的影响?非常感谢
  • 很高兴我能帮上忙。掩码只是一组标志,指示您是否希望视图随其父视图一起增长或缩小。它受到重新加载的影响,因为表格视图可能调整了它包含的单元格的大小,导致它增长。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-10-04
  • 2016-04-17
  • 1970-01-01
  • 1970-01-01
  • 2018-08-05
相关资源
最近更新 更多