ios UITableView:显示最后一个单元格的分隔符的正确方法
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/19767543/
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
UITableView: the proper way to display a separator for the last cell
提问by dariaa
The question is what's the right-most way to display a separator in the last cell in a table/section.
问题是在表格/部分的最后一个单元格中显示分隔符的最正确方式是什么。
Basically this is what I am after.
基本上这就是我所追求的。
This is from the native music app, which makes me think that it should be possible to achieve just by means of
UITableView
, they would not be using some private API for cell separators, right?
这是来自本机音乐应用程序,这让我认为应该可以通过 来实现
UITableView
,他们不会使用某些用于单元格分隔符的私有 API,对吗?
I know you can get away without using actual separators, but adding one pixel line in the bottom of the cell. But I'm not a fan of this approach because
我知道你可以不使用实际的分隔符,而是在单元格底部添加一个像素线。但我不喜欢这种方法,因为
- When a cell is selected/highlighted itsseparator andthe separator of the previous cellare automatically hidden (see the second screenshot with "You've got to be crazy" selected). And this is something I want UITableView to handle instead of doing myself if I use one-pixel line (which is especially handy when cell separators do not extend all the way to the edge of the table view, separators and selected cell background do not look nice together).
- I would like to keep my cells as flat as possible for scrolling performance.
- 当一个单元格被选中/突出显示时,它的分隔符和前一个单元格的分隔符会自动隐藏(参见第二个屏幕截图,选择了“你必须疯了”)。如果我使用单像素线,这是我希望 UITableView 处理而不是自己处理的事情(当单元格分隔符没有一直延伸到表格视图的边缘时,这特别方便,分隔符和选定的单元格背景看起来不在一起很好)。
- 我想让我的单元格尽可能平坦以提高滚动性能。
Also there is something in UITableView reference that makes me think that there is an easy way to get what I want:
UITableView 参考中还有一些东西让我觉得有一种简单的方法可以得到我想要的东西:
In iOS 7 and later, cell separators do not extend all the way to the edge of the table view. This property sets the default inset for all cells in the table, much like rowHeight sets the default height for cells. It is also used for managing the “extra” separators drawn at the bottom of plain style tables.
在 iOS 7 及更高版本中,单元格分隔符不会一直延伸到表格视图的边缘。此属性设置表格中所有单元格的默认插入,很像 rowHeight 设置单元格的默认高度。它还用于管理在普通样式表底部绘制的“额外”分隔符。
Does somebody know how exactly to use these “extra” separators drawn at the bottom of plain style tables? Because this is exactly what I need.
I thought assigning separatorInset
to the UITableView
, not UITableViewCell
would do the trick, but it does not, the last cell is still missing its separator.
有人知道如何使用这些在普通样式表底部绘制的“额外”分隔符吗?因为这正是我所需要的。我认为分配separatorInset
给UITableView
, notUITableViewCell
会奏效,但事实并非如此,最后一个单元格仍然缺少分隔符。
Right now I only see one option: to have a custom section footer to mimic the separator for the last cell. And this is not good, especially if you want to have an actual section footer using tableView:titleForFooterInSection:
method.
现在我只看到一个选项:使用自定义节页脚来模拟最后一个单元格的分隔符。这并不好,特别是如果您想使用tableView:titleForFooterInSection:
方法拥有实际的节页脚。
回答by Timo Cengiz
This worked flawlessly for me to add a separator to the last cell. have fun!
这对我来说完美无缺地为最后一个单元格添加了一个分隔符。玩得开心!
self.tableView.tableFooterView = [[UIView alloc] init];
回答by lukszar
When you add headerView or footerView to your TableView, last separator line will disappear.
当您将 headerView 或 footerView 添加到您的 TableView 时,最后一个分隔线将消失。
Example below will let you make workaround for showing separator on the last cell. The only thing you have to implement more is to make this separator disappearing after selecting cell, so behavior is the same like in the rest of cells.
下面的示例将让您解决在最后一个单元格上显示分隔符的方法。您唯一需要执行的操作是在选择单元格后使此分隔符消失,因此行为与其他单元格中的相同。
For Swift 4.0
对于 Swift 4.0
override func tableView(_ tableView: UITableView, viewForFooterInSection section: Int) -> UIView? {
let result = UIView()
// recreate insets from existing ones in the table view
let insets = tableView.separatorInset
let width = tableView.bounds.width - insets.left - insets.right
let sepFrame = CGRect(x: insets.left, y: -0.5, width: width, height: 0.5)
// create layer with separator, setting color
let sep = CALayer()
sep.frame = sepFrame
sep.backgroundColor = tableView.separatorColor?.cgColor
result.layer.addSublayer(sep)
return result
}
回答by SimonFrr
I just found something that works for me. In a few words: give your UITableView a tableFooterView and set its frame's height to 0. This makes an actual separator show, with the right insets.
我刚刚找到了对我有用的东西。简而言之:给你的 UITableView 一个 tableFooterView 并将其框架的高度设置为 0。这将显示实际的分隔符,并带有正确的插图。
In more details: if you are using the storyboard, drag a UIView to the bottom of your Table View (in the tree view on the left) so it shows just below Table View Cell, at the same hierarchical level. This creates a tableFooterView. Of course this can be done programmatically as well.
更详细地说:如果您使用故事板,请将 UIView 拖到 Table View 的底部(在左侧的树视图中),以便它显示在 Table View Cell 下方,处于相同的层次结构级别。这将创建一个 tableFooterView。当然,这也可以以编程方式完成。
Then, in your UITableViewController's implementation:
然后,在你的 UITableViewController 的实现中:
UIView *footerView = self.tableView.tableFooterView;
CGRect footerFrame = footerView.frame;
footerFrame.size.height = 0;
[footerView setFrame:footerFrame];
Let me know if that works for you! It might also work for the first separator if you use a tableHeaderView instead, I haven't tried it though.
让我知道这是否适合您!如果您改用 tableHeaderView,它也可能适用于第一个分隔符,不过我还没有尝试过。
回答by Nii Mantse
So here's a super simple solution in Swift 4which works:
所以这是Swift 4 中的一个超级简单的解决方案,它有效:
Inside override func viewDidLoad(){}
, I simply implemented this line of code:
在里面override func viewDidLoad(){}
,我简单地实现了这行代码:
self.tableView.tableFooterView = UIView(frame: .zero)
Hence it ensures that only the last cell gets the separator inset.
因此,它确保只有最后一个单元格获得分隔符插图。
This worked perfectly for me, hope it does for you too!
这对我来说非常有效,希望它也适用于你!
回答by artud2000
You can do something like this if you are not using sections:
如果您不使用部分,则可以执行以下操作:
- (void)viewDidLoad
{
self.tableView.tableFooterView = [[UIView alloc] initWithFrame:CGRectMake(insetLeftSide, 0, width - insetRightSide, 1)];
}
If you are using sections implement the footer in each section as a one point View in the methods
如果您使用部分将每个部分中的页脚实现为方法中的一个点视图
- (UIView *)tableView:(UITableView *)tableView viewForFooterInSection:(NSInteger)section
{
}
- (CGFloat)tableView:(UITableView *)tableView heightForFooterInSection:(NSInteger)section
{
}
This will allow you to have a separator for your last cell which in fact is not a separator is a footer that you can play with it and make it look like a separator
这将允许您为最后一个单元格设置一个分隔符,实际上它不是一个分隔符,而是一个页脚,您可以使用它并使其看起来像一个分隔符
回答by Ilario
this will do exactly what you want .. even though the line will take the entire width of the cell:
这将完全按照您的要求执行 .. 即使该行将占用单元格的整个宽度:
in - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
在 - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
self.tableView.separatorStyle = UITableViewCellSeparatorStyleSingleLine;
self.tableView.separatorColor = [UIColor redColor];
self.tableView.separatorInset = UIEdgeInsetsZero;
回答by Cyupa
I had a similar issue and found a workaround. Apple hides the last uitableviewcell separator and then displays it if you select the cell or if you call select and deselect on that cell.
我遇到了类似的问题并找到了解决方法。Apple 会隐藏最后一个 uitableviewcell 分隔符,然后在您选择单元格或在该单元格上调用 select 和 deselect 时显示它。
So I taught the best is in - (void)layoutSubviews
. The separator view is called _separatorView
and it's a private property. Using the cell's selected / highlighted states you can come up with something like this:
所以我教的最好的是在- (void)layoutSubviews
。分隔符视图被调用_separatorView
,它是一个私有属性。使用单元格的选定/突出显示状态,您可以想出这样的事情:
- (void)layoutSubviews
{
// Call super so the OS can do it's layout first
[super layoutSubviews];
// Get the separator view
UIView *separatorView = [self valueForKey:@"_separatorView"];
// Make the custom inset
CGRect newFrame = CGRectMake(0.0, 0.0, self.bounds.size.width, separatorView.frame.size.height);
newFrame = CGRectInset(newFrame, 15.0, 0.0);
[separatorView setFrame:newFrame];
// Show or hide the bar based on cell state
if (!self.selected) {
separatorView.hidden = NO;
}
if (self.isHighlighted) {
separatorView.hidden = YES;
}
}
Something like this.
像这样的东西。
回答by Vilém Kurz
In iOS 8, if you have a plain style UITableView, and add a footer, the last separator is gone. However, you can easily recreate it by adding a custom separator view to the footer.
在 iOS 8 中,如果你有一个简单的 UITableView 样式,并添加一个页脚,最后一个分隔符就消失了。但是,您可以通过向页脚添加自定义分隔符视图轻松地重新创建它。
This example exactly mimics Today Widget separator style
此示例完全模仿 Today Widget 分隔符样式
override func tableView(tableView: UITableView, viewForFooterInSection section: Int) -> UIView? {
//create footer view
let result = UIView()
result.frame.size.height = tableView.rowHeight
//recreate last cell separator, which gets hidden by footer
let sepFrame = CGRectMake(15, -0.5, tableView.frame.width, 0.5);
let vibrancyEffectView = UIVisualEffectView.init(effect: UIVibrancyEffect.notificationCenterVibrancyEffect())
vibrancyEffectView.frame = sepFrame
vibrancyEffectView.contentView.backgroundColor = tableView.separatorColor
result.addSubview(vibrancyEffectView)
return result
}
回答by Cocatrix
Swift 3
斯威夫特 3
I found this old issue, so I tried the same in Swift:
我发现了这个老问题,所以我在 Swift 中尝试了同样的方法:
tableView.tableFooterView = UIView()
tableView.tableFooterView?.height = 0 // Maybe not necessary
But it lead to another problem (in my case). So I solved it differently. I added an extra cell at the end of this section, empty and with height equal to zero:
但这会导致另一个问题(就我而言)。所以我以不同的方式解决了它。我在本节末尾添加了一个额外的单元格,空且高度为零:
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return previousNumberOfRows + 1
}
override func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
return indexPath.row == previousNumberOfRows ? 0 : previousCellHeight
}
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
if indexPath.row == items.count {
return UITableViewCell()
} else {
previousCellInitialization()
}
This is a less concise solution, but works in more cases, if you have multiple sections, existing footer view(s)...
这是一个不太简洁的解决方案,但适用于更多情况,如果您有多个部分,现有的页脚视图...
回答by Oren
If you add an empty footer then the tableview will remove all the remaining line separators (for non-existent cells) but will still include the separator for the last cell:
如果您添加一个空的页脚,那么 tableview 将删除所有剩余的行分隔符(对于不存在的单元格),但仍将包含最后一个单元格的分隔符:
- (UIView *)tableView:(UITableView *)tableView viewForFooterInSection:(NSInteger)section
{
return [UIView new];
}