在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; }
我做的是这样的:
- 在单元格的内容视图下添加一个新的子视图。
- 将单元格作为selectedBackgroundView进行连接。
- 添加新的选定背景视图的子视图。 将其设置为从左侧开始16px,覆盖其余宽度,高1px,从顶部向下1px,背景色为90%白色。
在我的情况下,我不希望我的行被选中时着色,所以我将所选的背景视图清除了,但是可以使用任何你喜欢的颜色。
此外,我没有使用自动布局,所以只需适当地设置我的尺寸。 我认为自动布局,你将不得不build立适当的约束。
对我来说,这完全解决了这个问题(尽pipe我同意这确实是ios 7中的一个错误)。
这里的解决scheme并没有帮助我。 在大多数情况下,build议删除select,但我希望细胞保持它的select状态。 所以这个想法是禁用默认的分隔线,并使用自己的分隔线。 我试过这个,但是我遇到了问题(你可以在这里阅读更多的信息)。 主要的问题是在accessorView
区域画线。 它只适用于iOS 8,但我也需要iOS 7的解决scheme。
我的要求是:
- select应该保持
- 线不应该消失(特别是在细胞被选中的情况下)
- 选定单元格上方的分隔线也不会消失
特别是第三点提出了问题,因为iOS对UITableViewCell
的交叉使用了一种抗锯齿效果。 正如我发现,只发生在iPad上。 它在每个方向上有大约一个点的大小(当前选定的单元格,上面的单元格),以便单元格上的一条线即使在单元格本身(而不是默认的单元格)上绘制也会消失。 如果这条线位于上面的单元格上或在选定的单元格上,则没有区别。 这个特殊的渲染效果隐藏了我的线条。
解决scheme如下所示:
- 使用
backgroundView
绘制两条线:顶部(iPad的y方向为+1点,iPhone的y方向为0点),底部为1。 所以它不会被select效果所覆盖。 - 创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
- 如何将渐变应用于iOS Swift应用的背景视图
- 致命错误:错误或损坏的AST文件 – Xcode
- Xcode 5和资产目录:如何引用LaunchImage?
- 该应用程序在Payload / <Appname> .app / <应用程序名称>:解码器中引用非公共select器
- UITableViewCell与iOS 7中的UITextView高度?
- ld:找不到符号dyld_stub_binding_helper,通常在crt1.o / dylib1.o / bundle1.o中用于架构i386 xcode 5
- 核心数据和iOS 7:持久存储的不同行为
- 当iOS 7中显示工作表/提醒时,如何在自定义绘制的控件上将tintColor设置为灰色?
- 如何检测iOS 7中拒绝的麦克风input权限