在iOS7中select单元格时,UITableView分隔线会消失

在我的tableView我设置单元格之间的分隔线。 我允许select多个单元格。 这里是我设置选定单元格背景颜色的代码:

UIView *cellBackgroundColorView = [[UIView alloc] initWithFrame:cell.frame]; [cellBackgroundColorView setBackgroundColor:[UIColor darkGray]]; [cell setSelectedBackgroundView:cellBackgroundColorView]; 

问题是,如果select了两个相邻的单元格,则在iOS7中它们之间没有分隔线,而在iOS6中有(如预期的那样)。

我什至尝试设置cellBackgroundColorView的框架高度cell.frame - 1.0 ,但也不起作用。

有任何想法吗?

我还没有得到它的底部(乍一看,它似乎像一个iOS 7的错误..),但我find了一个解决方法。 在tableView:didSelectRowAtIndexPath中,如果您在下面发送这两个消息,则问题将被视觉parsing(可能的性能成本)。

 [tableView deselectRowAtIndexPath:indexPath animated:YES]; [tableView reloadRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationAutomatic]; 

为了这个工作(对我来说),deselectRowAtIndexPath:animated:必须包含animation:YES。 用于reloadRowsAtIndexPaths:withRowAnimation的animation无关紧要。

将此代码添加到位于indexpath的行的单元格中

 cell.selectionStyle = UITableViewCellSelectionStyleNone; cell.textLabel.backgroundColor = [UIColor clearColor]; 

在我的情况下,我是animation行,所以只需要把这样的一些:

 -(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath { [tableView beginUpdates]; [tableView deselectRowAtIndexPath:indexPath animated:NO]; //if you are doing any animation you have deselect the row here inside. [tableView endUpdates]; } 

@ samvermette的答案解决了我的问题,但我不得不先取消选定的行。

 - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath { //Deselect Row [self.tableView deselectRowAtIndexPath:indexPath animated:YES]; // fix for separators bug in iOS 7 self.tableView.separatorStyle = UITableViewCellSeparatorStyleNone; self.tableView.separatorStyle = UITableViewCellSeparatorStyleSingleLine; } 

这似乎仍然是iOS 7.0.3的一个问题,但是我已经用伪造分隔符的简单方法来解决这个问题。

首先将UITableView的分隔符样式设置为UITableViewCellSeparatorStyleNone 。 然后,您可以使用自定义的UITableViewCell子类来伪造单元格之间的分隔符,以select和未选中状态:

 @implementation MyTableViewCellSubclass - (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier { self = [super initWithStyle:style reuseIdentifier:reuseIdentifier]; if (self) { CGRect frame = self.bounds; frame.origin.y = frame.size.height - 1.f; frame.size.height = 1.f; // Selected background view // UIView * separatorView = [[UIView alloc] initWithFrame:frame]; separatorView.backgroundColor = [UIColor darkGrayColor]; separatorView.autoresizingMask = UIViewAutoresizingFlexibleWidth|UIViewAutoresizingFlexibleTopMargin; UIView * selectedView = [[UIView alloc] initWithFrame:self.bounds]; selectedView.backgroundColor = [UIColor lightGrayColor]; [selectedView addSubview:separatorView]; self.selectedBackgroundView = selectedView; // Add separator view to content view for unselected state // UIView * separatorView2 = [[UIView alloc] initWithFrame:frame]; separatorView2.backgroundColor = [UIColor darkGrayColor]; separatorView2.autoresizingMask = UIViewAutoresizingFlexibleWidth|UIViewAutoresizingFlexibleTopMargin; [self.contentView addSubview:separatorView2]; } return self; } @end 

这个简单的调用在iOS 8上为我做了。

 - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath { // .... [tableView deselectRowAtIndexPath:indexPath animated:YES] // .... } 

如果你让iOS应用它自己的默认选定单元格样式,就会发生这种情况。 我发现迄今为止最好的解决办法是覆盖选定的属性实现:

在你的单元格子类实现中:

  @synthesize selected = _selected; 

在初始化方法中:

  // problem actually is caused when you set following // to UITableViewCellSelectionStyleDefault, so: [self setSelectionStyle:UITableViewCellSelectionStyleNone]; 

重写方法:

  - (BOOL)selected { return _selected; } - (void)setSelected:(BOOL)selected animated:(BOOL)animated { _selected = selected if (selected) { // apply your own selected style } else { // apply your own deselected style } } 

我解决了这个问题(hackishly)通过重新加载不只是选定的单元格,但也重新加载一个正确的上面。 上述其他解决scheme都没有为我工作。

  NSIndexPath *indexPathOfCellAbove = [NSIndexPath indexPathForRow:(indexPath.row - 1) inSection:indexPath.section]; if (indexPath.row > 0) [self.tableView reloadRowsAtIndexPaths:@[indexPathOfCellAbove, indexPath] withRowAnimation:UITableViewRowAnimationNone]; else [self.tableView reloadRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationNone]; 

– cellForRowAtIndexPath

 Create two separator views (sv1, sv2) [cell addsubview:sv1]; [cell.selectedBackgroundView addsubview:sv2]; 

– didSelectRowAtIndexPath

 [tableView deselectRowAtIndexPath:indexPath animated:NO]; 

我遇到这个问题时,我设置我的单元格的select样式没有编程,然后当我select我的表格单元格编程。

  func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { let cell: UITableViewCell! if tableView == self.jobLevelTableView { let cell = tableView.dequeueReusableCell(withIdentifier: "cellIdentifier", for: indexPath) as! CheckboxCell // for testing purposes let checked = true // I used M13Checkbox here, in case anybody was wondering cell.checkbox.setCheckState(checked ? .checked : .unchecked, animated: false) if checked { tableView.selectRow(at: indexPath, animated: true, scrollPosition: .none) } // CULPRIT cell.selectionStyle = .none return cell } cell = UITableViewCell() return cell } 

当我在故事板上设置select样式(并删除相应的代码)时,问题就消失了!

故事板很有用

你也可以尝试设置分隔符为0.我做到了这一点,它解决了这个问题,但权衡是你失去了插图的好看。

单细胞select也存在此问题。

另一个解决scheme是重新加载表视图,select,然后取消select:

 self.selectedIndex = inIndexPath.row; [inTableView reloadData]; [inTableView selectRowAtIndexPath:inIndexPath animated:NO scrollPosition:UITableViewScrollPositionNone]; [inTableView deselectRowAtIndexPath:inIndexPath animated:YES]; 

这摆脱了我在Mark的解决scheme中看到的微妙的graphicsselect故障。

这个解决scheme不会帮助任何不在他的单元格上使用backgroundView的人:

 - (void) tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath { [cell setBackgroundColor:[UIColor grayColor]]; } 

这种方式恼人的视觉效果大大减less,而不必重新加载表。 当然,你可以用任何可以帮助你改善结果的grayColor来改变你的情况

用这个:

 - (BOOL)tableView:(UITableView *)tableView shouldHighlightRowAtIndexPath:(NSIndexPath *)indexPath
 {
     UITableViewCell * cell =(UITableViewCell *)[tableView cellForRowAtIndexPath:indexPath];
     UIView * selectionColor = [[UIView alloc] init];
     selectionColor.backgroundColor = [UIColor clearColor];
     cell.selectedBackgroundView = selectionColor;
     // 71
     UIView * separatorLineView = [[UIView alloc] initWithFrame:CGRectMake(0,71,320,2)]; ///根据需要更改大小,其中 -  y  - 坐标,320  - 重量,2-高度
   // separatorLineView.backgroundColor = [UIColor colorWithPatternImage:[UIImage imageNamed:@“divider_goriz.png”]]; //你也可以把图像放在这里
     separatorLineView.backgroundColor = [UIColor redColor];
     [cell.selectedBackgroundView addSubview:separatorLineView];
    返回YES;
 }

我做的是这样的:

  1. 在单元格的内容视图下添加一个新的子视图。
  2. 将单元格作为selectedBackgroundView进行连接。
  3. 添加新的选定背景视图的子视图。 将其设置为从左侧开始16px,覆盖其余宽度,高1px,从顶部向下1px,背景色为90%白色。

在我的情况下,我不希望我的行被选中时着色,所以我将所选的背景视图清除了,但是可以使用任何你喜欢的颜色。

此外,我没有使用自动布局,所以只需适当地设置我的尺寸。 我认为自动布局,你将不得不build立适当的约束。

对我来说,这完全解决了这个问题(尽pipe我同意这确实是ios 7中的一个错误)。

这里的解决scheme并没有帮助我。 在大多数情况下,build议删除select,但我希望细胞保持它的select状态。 所以这个想法是禁用默认的分隔线,并使用自己的分隔线。 我试过这个,但是我遇到了问题(你可以在这里阅读更多的信息)。 主要的问题是在accessorView区域画线。 它只适用于iOS 8,但我也需要iOS 7的解决scheme。

我的要求是:

  • select应该保持
  • 线不应该消失(特别是在细胞被选中的情况下)
  • 选定单元格上方的分隔线也不会消失

特别是第三点提出了问题,因为iOS对UITableViewCell的交叉使用了一种抗锯齿效果。 正如我发现,只发生在iPad上。 它在每个方向上有大约一个点的大小(当前选定的单元格,上面的单元格),以便单元格上的一条线即使在单元格本身(而不是默认的单元格)上绘制也会消失。 如果这条线位于上面的单元格上或在选定的单元格上,则没有区别。 这个特殊的渲染效果隐藏了我的线条。

解决scheme如下所示:

  1. 使用backgroundView绘制两条线:顶部(iPad的y方向为+1点,iPhone的y方向为0点),底部为1。 所以它不会被select效果所覆盖。
  2. 创build的背景视图只能用于选定的状态( cell.selectedBackgroundView = selectedBackground )。 对其他单元格启用默认的分隔线。

我有一个在这里发布的C#代码工作的例子,虽然你必须适应你的需求。 现在我的select问题没有了!

对于我来说,当我以编程方式设置时,

 cell.selectionStyle = UITableViewCellSelectionStyleNone; 

当我在故事板中设置此属性时,它工作正常。

太激动了,我解决了这个问题。 在自定义单元格中添加以下方法调用,并设置颜色分隔符和框架。 我将隐藏单元格分隔符,然后在超级视图中自定义装载分隔符上的视图。 当这个问题解决的朋友select影响分隔符单元格

 @interface MyCustomTableViewCell(){ UIView *customSeparatorView; CGFloat separatorHight; } @property (nonatomic,weak)UIView *originSeparatorView; @end -(void)setSeparatorWithInset:(UIEdgeInsets)insets{ if (customSeparatorView) { customSeparatorView.frame = CGRectMake(insets.left, insets.top,self.width - insets.left - insets.right, self.originSeparatorView.height-insets.bottom - insets.top); self.originSeparatorView.hidden = YES; self.originSeparatorView.alpha = 0; }else{ for (int i = ([self.contentView.superview.subviews count] - 1); i >= 0; i--) { UIView *subView = self.contentView.superview.subviews[i]; if ([NSStringFromClass(subView.class) hasSuffix:@"SeparatorView"]) { self.originSeparatorView = subView; subView.hidden = YES; subView.alpha = 0; subView.frame = CGRectMake(insets.left, insets.top,self.width - insets.left - insets.right, subView.height-insets.bottom - insets.top); customSeparatorView = [[subView superview] viewWithTag:separatorViewTag]; if (!customSeparatorView) { customSeparatorView = [[UIView alloc] initWithFrame:subView.frame]; customSeparatorView.tag = separatorViewTag; [[subView superview] addSubview:customSeparatorView]; customSeparatorView.backgroundColor = [subView backgroundColor]; } [[subView superview] bringSubviewToFront:customSeparatorView]; break; } } } } -(void)setSeparatorColorWithColor:(UIColor *)sepColor{ if (customSeparatorView) { customSeparatorView.backgroundColor = sepColor; self.originSeparatorView.hidden = YES; self.originSeparatorView.alpha = 0; }else { for (int i = ([self.contentView.superview.subviews count] - 1); i >= 0; i--) { UIView *subView = self.contentView.superview.subviews[i]; if ([NSStringFromClass(subView.class) hasSuffix:@"SeparatorView"]) { self.originSeparatorView = subView; if (sepColor) { subView.hidden = YES; subView.alpha = 0; subView.backgroundColor = sepColor; customSeparatorView = [[subView superview] viewWithTag:separatorViewTag]; if (!customSeparatorView) { customSeparatorView = [[UIView alloc] initWithFrame:subView.frame]; customSeparatorView.tag = separatorViewTag; [[subView superview] addSubview:customSeparatorView]; customSeparatorView.backgroundColor = [subView backgroundColor]; } [[subView superview] bringSubviewToFront:customSeparatorView]; } break; } } } } -(void)layoutSubviews{ [super layoutSubviews]; [self setSeparatorWithInset:UIEdgeInsetsMake(0, 0, 0, 0)]; [self setSeparatorColorWithColor:[UIColor colorWithRed:31/255.0 green:32/255.0f blue:35/255.0 alpha:0.2]]; } 

在beginUpdates和endUpdates之后,重新加载数据的是什么解决了我的问题:

  private func animateCellHeighChangeForTableView(tableView: UITableView, withDuration duration: Double) { UIView.animateWithDuration(duration) { () -> Void in tableView.beginUpdates(); tableView.endUpdates(); tableView.reloadData(); } } 

对于那些在Swift中寻找解决scheme的人来说,这个问题已经解决了。 在你的cellForRowAtIndexPath方法中,在你调用dequeueReusableCellWithIdentifier ,你只需要将单元格的selectionStyle设置为.None

代码如下:

  override func tableView(tableView: UITableView?, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell { let cell:TextTableViewCell = tableView!.dequeueReusableCellWithIdentifier("textCell", forIndexPath: indexPath) as! TextTableViewCell cell.selectionStyle = .None // This fixes the disappearing border line issue