16

这似乎是一个简单的问题,但我在寻找解决方案时遇到了困难,我希望这里有人可以提供帮助......

我正在使用 UITableViewStyleGrouped 制作 UITableView,我在表格视图的每个部分的第一行和第二行之间看到一条小的(1 像素)白线(见图)

差距的例子

这条线的原因似乎是每个部分中的第一个单元格比其他单元格高 1 个像素。当我将每组的初始单元格设置为 29 像素高(其他为 30 像素)时,间隙消失了,一切都很好。

虽然这是一种成功的解决方法,但我宁愿知道发生这种情况的原因,这样我就可以避免使用凌乱的黑客攻击。

供参考:

  • 我已经确保这不是我使用的背景图像的问题 - 它们都是 30 像素高,我用中间图像替换了顶部图像,结果相同。
  • 我通过设置 separatorStyle = UITableViewCellSeparatorStyleNone 删除了单元格之间的所有边框
  • 这种效果在 UITableViewStylePlain 上不会发生

任何帮助是极大的赞赏。

谢谢

表设置代码:

  myTable = [[UITableView alloc] initWithFrame:CGRectMake(TABLE_SHIFT_OFFSET,
                                                          DATE_SLIDER_HEIGHT - DATE_SLIDER_SHADOW_HEIGHT,
                                                          326,
                                                          self.view.frame.size.height - DATE_SLIDER_HEIGHT + DATE_SLIDER_SHADOW_HEIGHT) style:UITableViewStyleGrouped];
  myTable.backgroundColor = [UIColor clearColor];
  myTable.backgroundView = nil;
  myTable.separatorStyle = UITableViewCellSeparatorStyleNone;
  [self.view addSubview:myTable];
  myTable.dataSource = self;
  myTable.delegate = self;

单元设置代码:

- (float)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
  // This is a hack to make sure that a white line doesnt appear between the
  // first and second rows in the table, which happens for reasons I dont understand
  if (indexPath.row == 0) {
    return 29;
  }

  return 30;
}

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{     
  MyTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"satCell"];
  if (!cell)
  {
    cell = [[MyTableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:@"satCell"];
  }

  cell.backgroundView = nil;
  cell.backgroundView = [[UIView alloc] initWithFrame:CGRectZero];

  cell.backgroundColor = [UIColor whiteColor];
  int numberOfRowsInThisSection = [self tableView:tableView numberOfRowsInSection:indexPath.section];

  if (numberOfRowsInThisSection == 1)
  {
    cell.backingImage = self.singleWhite;
  }
  else if (indexPath.row == 0)
  {
    cell.backingImage = self.topWhite;
  }
  else if (indexPath.row % 2 == 0)
  {
    // Even row
    if (indexPath.row == numberOfRowsInThisSection - 1)
    {
      // Last row (even)
      cell.backingImage = self.botWhite;
    }
    else
    {
      // Normal row (even)
      cell.backingImage = self.midWhite;
    }
  }
  else if (indexPath.row % 2 == 1)
  {
    // Odd row
    if (indexPath.row == numberOfRowsInThisSection - 1)
    {
      // Last row (even)
      cell.backingImage = self.botDark;
    }
    else
    {
      // Normal row (odd)
      cell.backingImage = self.midDark;
    }
  }

  // Setup cell text [REMOVED FOR BREVITY]

  return cell;
}

在 MyTableViewCell 中设置背景图像的代码:

- (void)setBackingImage:(UIImage *)backingImage
{
  if (self.backingImage != backingImage)
  {
    _backingImage = nil;
    _backingImage = backingImage;
    self.backingView.image = backingImage;
  }
}

self.backingView 使用以下代码设置:

[[UIImageView alloc] initWithFrame:CGRectMake(7, 0, 307, 30)];
4

5 回答 5

3

这是一个已知问题,仅当您隐藏分组 tableView 的分隔符时才会发生,在另一个堆栈溢出问题中发生的情况完全相同。

简单来说,上下单元格使用了一个额外的,但是分隔符隐藏了它,所以解决方法是:

  1. 减去额外的间距(就像你已经做过的那样)
  2. 使背景成为重复图案或可拉伸图像(不是想推销自己,但我在上一个链接线程中给出的答案也解释了如何制作可拉伸图像)。
  3. 不要隐藏分隔符,而是将颜色与单元格的背景相匹配,使其看起来像是隐藏的。

选项 2 似乎是“最干净的”,并增加了支持 tableView 单元格可变高度的好处。

为什么它有这个额外的?只有苹果知道。

于 2013-07-20T07:55:58.467 回答
1

如果您执行以下操作,它将解决您的问题:摆脱“backingImage”(backingView)。而是使用单元格的backgroundView属性,只需将 分配UIImageView给它。现在,当您创建UIImageView背景时,请确保您可以UIImage像这样进行拉伸:

UIImage *bg = [UIImage imageName:@"filename.png"];
bg = [bg resizableImageWithCapInsets:UIEdgeInsetsMake(15, 0, 15, 0)];

注意:我假设您的图像高度为 30 点。查看您正在使用的图像可以垂直拉伸,我在这个例子中正在做的事情。为了节省更多内存,您也可以水平拉伸它,但您拥有的资产可能不适合这样做。

希望这可以帮助!

于 2013-07-20T01:04:03.350 回答
1

根据我的经验,分组表视图在每个部分的第一行和最后一行的高度上增加了 1 个点(不是像素!)。您应该能够通过添加调试代码来覆盖表格单元类上的 layoutSubviews,让它调用 super 然后打印 bounds.size.height 来看到这一点。

我认为这是为边框绘图提供空间,并且像您一样,我刚刚调整了为第一个和最后一个单元格的高度返回的值以抵消效果。这在 iOS 7 中很可能会改变,因为视觉外观已经改变。

[编辑] 这是一个很好的调试代码来检查视图层次结构。(您不能recursiveDescription直接调用,因为它是私有的,并且您的代码不会在默认的 Xcode 设置下编译。)

NSLog(@"%@", [self.view performSelector:@selector(recursiveDescription)]);

于 2013-06-19T21:07:44.900 回答
1

在分组表视图上没有分隔符的 iOS 8 上,我也遇到了问题。我的部分之间有 0.5f 点的差距。由于我的 tableview 后面的背景不是相同的颜色,所以非常明显。解决方案是用 1 px 高的空白 headerview 填充,然后用另一个视图溢出 1 px。奇迹般有效。

- (UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section {
    UIView *view = [[UIView alloc] initWithFrame:CGRectMake(0, 0, self.view.bounds.size.width, 1)];
    view.backgroundColor = [UIColor whiteColor];
    view.opaque = YES;
    view.clipsToBounds = NO;

    //Spill a view out by one pixel.
    UIView *subView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, self.view.bounds.size.width, 2)];
    subView.backgroundColor = [UIColor whiteColor];
    subView.opaque = YES;
    [view addSubview:subView];
    return view;
}

- (CGFloat)tableView:(UITableView *)tableView
heightForHeaderInSection:(NSInteger)section {
    return 1;
}
于 2015-06-16T19:11:36.743 回答
0

这对我来说是尖叫的部分标题。您是否覆盖 viewForHeaderInSection 方法?我最好的猜测是,每个部分中第一个单元格的边界以某种方式与该部分标题的边界相重叠。

尝试覆盖这些方法:

– tableView:viewForHeaderInSection:
– tableView:viewForFooterInSection:
– tableView:heightForHeaderInSection:
– tableView:heightForFooterInSection:
– tableView:willDisplayHeaderView:forSection:
– tableView:willDisplayFooterView:forSection:

和他们返回的东西一起玩。特别是 heightForHeaderInSection / viewForHeaderInSection / willDisplayHeaderView:ForSection:

于 2013-02-13T02:38:23.247 回答