分组UITableView中第一个和第二个单元格之间的1个像素间隙

时间:2013-01-31 23:28:28

标签: ios uitableview

这似乎是一个简单的问题,但我找到了解决方案的砖墙,我希望有人在这里帮助...

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

example of gap

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

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

供参考:

  • 我已经确定这不是我使用的背景图像的问题 - 它们都是30px高,我用中间图像替换了顶部图像,结果相同。
  • 我已通过设置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)];

5 个答案:

答案 0 :(得分:3)

这是一个已知问题,只有当您隐藏分组tableView的分隔符时才会发生,其他stack overflow question中发生的情况完全相同。

简单地说,顶部和底部单元格使用一个额外的,但是分隔符隐藏了它,因此解决方案是:

  1. 减去额外的间距(正如您所做的那样)
  2. 使背景成为重复图案或可伸缩图像(不尝试宣传自己,但前一个链接线程上的the answer I gave也解释了如何进行可伸缩图像。)
  3. 不要隐藏分隔符,但匹配是单元格背景的颜色,所以它看起来像是隐藏的。
  4. 选项2似乎是“最干净”的,并增加了支持tableView单元的可变高度的好处。

    为什么它有额外的?只有Apple知道。

答案 1 :(得分:1)

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

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

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

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

答案 2 :(得分:1)

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

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

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

希望这有帮助!

答案 3 :(得分:0)

这对我来说是尖叫的标题。你是否重写了viewForHeaderInSection方法?我最好的猜测是,每个部分中第一个单元格的边界以某种方式忽略了该部分标题的边界。

尝试覆盖这些方法:

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

并与他们的回归玩耍。特别是heightForHeaderInSection / viewForHeaderInSection / willDisplayHeaderView:ForSection:

答案 4 :(得分:0)

在iOS 8上,在分组的tableview上没有分隔符我也遇到了问题。我的部分之间有0.5f的差距。由于我的tableview背后的背景颜色不一样,所以非常引人注目。解决方案是填充1 px高的空白标题视图,然后用另一个视图将其溢出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;
}