ios UITableViewCell 分隔符在 iOS7 中消失
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/18924589/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
UITableViewCell Separator disappearing in iOS7
提问by B.S.
I have some strange issue with UITableView
only in iOS 7.
我UITableView
只在 iOS 7 中有一些奇怪的问题。
UITableViewCellSeparator
disappears above the first row and below the last row. Sometimes after selecting the rows or some scrolling actions it appears.
UITableViewCellSeparator
消失在第一行上方和最后一行下方。有时在选择行或一些滚动操作后它会出现。
In my case tableView
is loaded from the Storyboard
with UITableViewStylePlain
style. The problem is surely not in UITableViewCellSeparatorStyle
, which is not changed from default UITableViewCellSeparatorStyleSingleLine
.
在我的情况下tableView
是从Storyboard
withUITableViewStylePlain
样式加载的。问题肯定不在UITableViewCellSeparatorStyle
,它没有从默认更改UITableViewCellSeparatorStyleSingleLine
。
As I read at Apple Dev Forums(hereand here) other people have such problem and some workarounds are found, for example:
正如我在Apple Dev Forums(这里和这里)上读到的那样,其他人也有这样的问题,并且找到了一些解决方法,例如:
Workaround: disable the default selection and recreate the behaviour in a method
trigged by a tapGestureRecognizer.
But I am still searching for the reason of such separator strange behaviour.
但我仍在寻找这种分隔符奇怪行为的原因。
Any ideas?
有任何想法吗?
Update:As I saw in XCode 5.1 DP and iOS 7.1 beta, Apple tried to fix this problem. Now separator is shown as needed sometimes below the last row, after some refreshing, but not after tableview creation.
更新:正如我在 XCode 5.1 DP 和 iOS 7.1 beta 中看到的,Apple 试图解决这个问题。现在分隔符有时会根据需要显示在最后一行下方,经过一些刷新,但不是在创建 tableview 之后。
采纳答案by Ortwin Gentz
I dumped the subview hierarchy of affected cells and found that the _UITableViewCellSeparatorView
was set to hidden. No wonder it's not shown!
我转储了受影响单元格的子视图层次结构,发现它_UITableViewCellSeparatorView
被设置为隐藏。难怪没有显示!
I overrode layoutSubviews
in my UITableViewCell
subclass and now the separators are displayed reliably:
我覆盖layoutSubviews
了我的UITableViewCell
子类,现在分隔符可以可靠地显示:
Objective-C:
目标-C:
- (void)layoutSubviews {
[super layoutSubviews];
for (UIView *subview in self.contentView.superview.subviews) {
if ([NSStringFromClass(subview.class) hasSuffix:@"SeparatorView"]) {
subview.hidden = NO;
}
}
}
Swift:
斯威夫特:
override func layoutSubviews() {
super.layoutSubviews()
guard let superview = contentView.superview else {
return
}
for subview in superview.subviews {
if String(subview.dynamicType).hasSuffix("SeparatorView") {
subview.hidden = false
}
}
}
The other solutions proposed here didn't work consistently for me or seem clunky (adding custom 1 px footer views).
此处提出的其他解决方案对我来说并不一致,或者看起来很笨拙(添加自定义 1 px 页脚视图)。
回答by samvermette
This worked for me:
这对我有用:
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
// fix for separators bug in iOS 7
self.tableView.separatorStyle = UITableViewCellSeparatorStyleNone;
self.tableView.separatorStyle = UITableViewCellSeparatorStyleSingleLine;
回答by Emelie
I also had the problem with missing separator and I found out that the problem only occured when heightForRowAtIndexPath
was returning a decimal number. Solution:
我还与缺少分离的问题,我发现,当问题发生仅heightForRowAtIndexPath
是返回一个十进制数。解决方案:
override func tableView(tableView: UITableView, heightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat {
return ceil(yourHeight) // Ceiling this value fixes disappearing separators
}
回答by airpaulg
Did you try adding a UIView of height 1 in the header and the footer of the table with light gray background color? Basically it'll mock the first and last separators.
您是否尝试在表的页眉和页脚中添加高度为 1 的 UIView 并使用浅灰色背景色?基本上它会模拟第一个和最后一个分隔符。
回答by airpaulg
@samvermette
@samvermette
I fixed the problem by using this delegate methods. Now it doesn't flicker:
我通过使用这个委托方法解决了这个问题。现在它不闪烁:
-(void)tableView:(UITableView *)tableView didHighlightRowAtIndexPath:(NSIndexPath *)indexPath {
// fix for separators bug in iOS 7
tableView.separatorStyle = UITableViewCellSeparatorStyleNone;
tableView.separatorStyle = UITableViewCellSeparatorStyleSingleLine;
}
-(void)tableView:(UITableView *)tableView didUnhighlightRowAtIndexPath:(NSIndexPath *)indexPath {
// fix for separators bug in iOS 7
tableView.separatorStyle = UITableViewCellSeparatorStyleNone;
tableView.separatorStyle = UITableViewCellSeparatorStyleSingleLine;
}
回答by wrightak
We encountered this issue in our app. When the user selected a cell, a new table view was pushed onto the navigation controller stack and then when the user popped it off, the separator was missing. We solved it by putting [self.tableView deselectRowAtIndexPath:indexPath animated:NO];
in the didSelectRowAtIndexPath
table view delegate method.
我们在我们的应用程序中遇到了这个问题。当用户选择一个单元格时,一个新的表格视图被推送到导航控制器堆栈上,然后当用户弹出它时,分隔符丢失了。我们通过把解决它[self.tableView deselectRowAtIndexPath:indexPath animated:NO];
在didSelectRowAtIndexPath
表视图委托方法。
回答by conmulligan
I've found that the easiest solution is to, after reloading a cell, also reload the cell above:
我发现最简单的解决方案是在重新加载单元格后,也重新加载上面的单元格:
if (indexPath.row > 0) {
NSIndexPath *path = [NSIndexPath indexPathForRow:indexPath.row - 1 inSection:indexPath.section];
[self.tableView reloadRowsAtIndexPaths:@[path] withRowAnimation:UITableViewRowAnimationNone];
}
回答by redmoon7777
Here is an easier (although a bit messy) workaround if you need one, try selecting and deselecting the cell after the data is reloaded and the default animation is done.
如果您需要,这里有一个更简单(虽然有点混乱)的解决方法,请尝试在重新加载数据并完成默认动画后选择和取消选择单元格。
just add:
只需添加:
[self.tableView selectRowAtIndexPath:indexPath animated:NO scrollPosition:UITableViewScrollPositionNone];
[self.tableView deselectRowAtIndexPath:indexPath animated:NO];
回答by Lukas Petr
A simple and clean solution that works on both iOS 8 and iOS 9 (beta 1)
一个简单干净的解决方案,适用于 iOS 8 和 iOS 9(测试版 1)
Here is a simple, cleanand non-intrusive workaround. It involves calling a category method that will fix the separators.
这是一个简单、干净且非侵入性的解决方法。它涉及调用将修复分隔符的类别方法。
All you need to do is to walk down the hierarchy of the cell and un-hide the separator. Like this:
您需要做的就是沿着单元格的层次结构走下去并取消隐藏分隔符。像这样:
for (UIView *subview in cell.contentView.superview.subviews) {
if ([NSStringFromClass(subview.class) hasSuffix:@"SeparatorView"]) {
subview.hidden = NO;
}
}
What I recommend is to add this to a category on UITableViewCell, like this:
我建议将其添加到 UITableViewCell 上的一个类别中,如下所示:
@interface UITableViewCell (fixSeparator)
- (void)fixSeparator;
@end
@implementation UITableViewCell (fixSeparator)
- (void)fixSeparator {
for (UIView *subview in self.contentView.superview.subviews) {
if ([NSStringFromClass(subview.class) hasSuffix:@"SeparatorView"]) {
subview.hidden = NO;
}
}
}
@end
Because the separator can disappear in different cell than the one currently selected, it's probably a good idea to call this fix on allcells in the table view. For that, you can add a category to UITableView that goes like this:
由于分隔符可能会在与当前选定的单元格不同的单元格中消失,因此在表格视图中的所有单元格上调用此修复程序可能是个好主意。为此,您可以向 UITableView 添加一个类别,如下所示:
@implementation UITableView (fixSeparators)
- (void)fixSeparators {
for (UITableViewCell *cell in self.visibleCells) {
[cell fixSeparator];
}
}
@end
With this in place, you can call -fixSeparatos
on your tableView right after the action that causes them to disappear. In my case, it was after calling [tableView beginUpdates]
and [tableView endUpdates]
.
有了这个,您可以-fixSeparatos
在导致它们消失的操作之后立即调用您的 tableView。就我而言,是在调用[tableView beginUpdates]
和之后[tableView endUpdates]
。
As I stated at the beginning, I've tested this on both iOS 8 and iOS 9. I presume it will work even on iOS 7 but I don't have a way to try it there. As you are probably aware, this does fiddle with internals of the cell so it could stop working in some future release. And Apple could theoretically (0.001% chance) reject your app because of this, but I can't see how they could even find out what you are doing there (checking the suffix of a class can't be detected by static analyzers as something bad, IMO).
正如我在开头所说的那样,我已经在 iOS 8 和 iOS 9 上进行了测试。我认为它甚至可以在 iOS 7 上运行,但我没有办法在那里尝试。正如您可能知道的那样,这确实会影响单元的内部结构,因此它可能会在未来的某个版本中停止工作。理论上,Apple 可能(0.001% 的机会)因此拒绝您的应用程序,但我看不出他们是如何知道您在那里做什么的(检查类的后缀无法被静态分析器检测为某事)不好,海事组织)。
回答by Carlos D. álvaro
Based on @ortwin-gentz's comment, this solution works for me in iOS 9.
根据@ortwin-gentz 的评论,此解决方案适用于 iOS 9。
func fixCellsSeparator() {
// Loop through every cell in the tableview
for cell: UITableViewCell in self.tableView.visibleCells {
// Loop through every subview in the cell which its class is kind of SeparatorView
for subview: UIView in (cell.contentView.superview?.subviews)!
where NSStringFromClass(subview.classForCoder).hasSuffix("SeparatorView") {
subview.hidden = false
}
}
}
(Swift code)
(SWIFT代码)
I use fixCellsSeparator()function after calling endUpdates()in some methods of my tableView, for example:
我在 tableView 的某些方法中调用endUpdates()后使用fixCellsSeparator()函数,例如:
override func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
// Perform some stuff
// ...
self.tableView.endUpdates()
self.fixCellsSeparator()
}
I hope this solution will be helpfull for someone!
我希望这个解决方案对某人有帮助!