这是我用来隐藏iOS 11之前的单个UITableViewCell的分隔符的代码:
- (void)tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath {
if (indexPath.row == 0) {
// Remove separator inset
if ([cell respondsToSelector:@selector(setSeparatorInset:)]) {
[cell setSeparatorInset:UIEdgeInsetsMake(0, tableView.frame.size.width, 0, 0)];
}
// Prevent the cell from inheriting the Table View's margin settings
if ([cell respondsToSelector:@selector(setPreservesSuperviewLayoutMargins:)]) {
[cell setPreservesSuperviewLayoutMargins:NO];
}
// Explictly set your cell's layout margins
if ([cell respondsToSelector:@selector(setLayoutMargins:)]) {
[cell setLayoutMargins:UIEdgeInsetsMake(0, tableView.frame.size.width, 0, 0)];
}
}
}
在此示例中,分隔符将隐藏在每个部分的第一行中。我不想完全摆脱分隔符 - 只对某些行。
在iOS 11中,上述代码不起作用。单元格的内容完全向右推。
有没有办法在iOS 11中完成隐藏单个UITableViewCell分隔符的任务?
我先提前澄清一下,我确实知道我可以使用以下代码隐藏整个UITableView的分隔符(希望避免答案指示我这样做):
self.tableView.separatorStyle = UITableViewCellSeparatorStyleNone;
编辑:在下面的评论之后澄清一下,如果我包含setSeparatorInset行,代码会完全相同。因此,即使只有一行,单元格的内容也会一直向右推。
答案 0 :(得分:2)
如果您不想在UITableViewCell
添加自定义分隔符,我可以向您展示另一种需要考虑的解决方法。
由于分隔符的颜色是在UITableView
级别定义的,因此没有明确的方法可以根据UITableViewCell
实例更改它。苹果并不打算这样做,你唯一能做的就是破解它。
您需要的第一件事是访问分隔符视图。你可以用这个小扩展来做到这一点。
extension UITableViewCell {
var separatorView: UIView? {
return subviews .min { $0.frame.size.height < $1.frame.size.height }
}
}
如果您有权访问分隔符视图,则必须正确配置UITableView
。首先,将所有分隔符的全局颜色设置为.clear
(但不禁用它们!)
override func viewDidLoad() {
super.viewDidLoad()
tableView.separatorColor = .clear
}
接下来,为每个单元格设置分隔符颜色。您可以为每个颜色设置不同的颜色,具体取决于您。
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "SeparatorCell", for: indexPath)
cell.separatorView?.backgroundColor = .red
return cell
}
最后,对于该部分中的每个第一行,将分隔符颜色设置为.clear
。
func tableView(_ tableView: UITableView, willDisplay cell: UITableViewCell, forRowAt indexPath: IndexPath) {
if indexPath.row == 0 {
cell.separatorView?.backgroundColor = .clear
}
}
首先,让我们考虑一下UITableViewCell
的结构。如果您打印出单元格的subviews
,您将看到以下输出。
<UITableViewCellContentView: 0x7ff77e604f50; frame = (0 0; 328 43.6667); opaque = NO; gestureRecognizers = <NSArray: 0x608000058d50>; layer = <CALayer: 0x60400022a660>>
<_UITableViewCellSeparatorView: 0x7ff77e4010c0; frame = (15 43.5; 360 0.5); layer = <CALayer: 0x608000223740>>
<UIButton: 0x7ff77e403b80; frame = (0 0; 22 22); opaque = NO; layer = <CALayer: 0x608000222500>>
如您所见,有一个视图包含内容,分隔符和附件按钮。从这个角度来看,您只需要访问分隔符视图并修改它的背景。不幸的是,这并不容易。
让我们看一下视图调试器中的UITableViewCell
。如您所见,有两个分隔符视图。您需要访问调用willDisplay:
时不存在的底部。这是第二个hacky部分发挥作用的地方。
当您检查这两个元素时,您将看到第一个(从顶部)背景颜色设置为nil
,第二个背景颜色设置为您为整个{指定的值{1}}。在这种情况下,具有颜色的分隔符覆盖没有颜色的分隔符。
要解决这个问题,我们必须“扭转”这种情况。我们可以将所有分隔符的颜色设置为UITableView
,这将揭示我们可以访问的分隔符。最后,我们可以将可访问分隔符的背景颜色设置为所需的颜色。
答案 1 :(得分:1)
首先通过tableView.separatorStyle = .none
隐藏所有分隔符。然后将UITableViewCell
子类修改为以下内容:
class Cell: UITableViewCell {
var separatorLine: UIView?
...
}
将以下内容添加到tableView(_:cellForRowAt:)
的方法正文中:
if cell.separatorLine == nil {
// Create the line.
let singleLine = UIView()
singleLine.backgroundColor = UIColor.lightGray.withAlphaComponent(0.5)
singleLine.translatesAutoresizingMaskIntoConstraints = false
// Add the line to the cell's content view.
cell.contentView.addSubview(singleLine)
let singleLineConstraints = [singleLine.leadingAnchor.constraint(equalTo: cell.contentView.leadingAnchor, constant: 8),
singleLine.trailingAnchor.constraint(equalTo: cell.contentView.trailingAnchor),
singleLine.topAnchor.constraint(equalTo: cell.contentView.bottomAnchor, constant: -1),
singleLine.bottomAnchor.constraint(equalTo: cell.contentView.bottomAnchor, constant: 0)]
cell.contentView.addConstraints(singleLineConstraints)
cell.separatorLine = singleLine
}
cell.separatorLine?.isHidden = [Boolean which determines if separator should be displayed]
此代码在Swift中,因此您必须为Objective-C转换执行此操作,并确保继续进行版本检查。在我的测试中,我根本不需要使用tableView(_:willDisplayCell:forRowAt:)
,而是所有内容都在cellForRowAtIndexPath:
方法中。
答案 2 :(得分:1)
最好的方式IMO只是添加一个高度为1pt的简单UIView。 我编写了以下协议,使您可以在任何您喜欢的UITableViewCell中使用它:
// Base protocol requirements
protocol SeperatorTableViewCellProtocol: class {
var seperatorView: UIView! {get set}
var hideSeperator: Bool! { get set }
func configureSeperator()
}
// Specify the separator is of a UITableViewCell type and default separator configuration method
extension SeperatorTableViewCellProtocol where Self: UITableViewCell {
func configureSeperator() {
hideSeperator = true
seperatorView = UIView()
seperatorView.backgroundColor = UIColor(named: .WhiteThree)
contentView.insertSubview(seperatorView, at: 0)
// Just constraint seperatorView to contentView
seperatorView.setConstant(edge: .height, value: 1.0)
seperatorView.layoutToSuperview(.bottom)
seperatorView.layoutToSuperview(axis: .horizontally)
seperatorView.isHidden = hideSeperator
}
}
你这样使用它:
// Implement the protocol with custom cell
class CustomTableViewCell: UITableViewCell, SeperatorTableViewCellProtocol {
// MARK: SeperatorTableViewCellProtocol impl'
var seperatorView: UIView!
var hideSeperator: Bool! {
didSet {
guard let seperatorView = seperatorView else {
return
}
seperatorView.isHidden = hideSeperator
}
}
override func awakeFromNib() {
super.awakeFromNib()
configureSeperator()
hideSeperator = false
}
}
这就是全部。您可以自定义任何UITableViewCell子类以使用分隔符。
从tableView设置分隔符可见性:willDisplayCell:forRowAtIndexPath by:
cell.hideSeperator = false / true
答案 3 :(得分:0)
实际上,当我使用UITableView时,我总是创建自定义单元类和分隔符,并且通常将我自己的分隔符设置为UIView,高度为1,左右约束,在您的情况下,请执行以下步骤: 1.创建自定义单元格。 2.添加UIView作为分隔符。 3.将此分隔符链接到您的自定义类。 4.将hideSeparator方法添加到您的班级。
translate()
5。隐藏所需的任何单元格的分隔符。
希望能解决你的问题。
答案 4 :(得分:0)
我也遵循这种模式一次。多年来,我对其进行了调整。就在今天,我必须删除directionalLayoutMargins
部分才能使其工作。现在,我的功能如下:
func adjustCellSeparatorInsets(at indexPath: IndexPath,
for modelCollection: ModelCollection,
numberOfLastSeparatorsToHide: Int) {
guard modelCollection.isInBounds(indexPath) else { return }
let model = modelCollection[indexPath]
var insets = model.separatorInsets
let lastSection = modelCollection[modelCollection.sectionCount - 1]
let shouldHideSeparator = indexPath.section == modelCollection.sectionCount - 1
&& indexPath.row >= lastSection.count - numberOfLastSeparatorsToHide
// Don't show the separator for the last N rows of the last section
if shouldHideSeparator {
insets = NSDirectionalEdgeInsets(top: 0, leading: 9999, bottom: 0, trailing: 0)
}
// removing separator inset
separatorInset = insets.edgeInsets
// prevent the cell from inheriting the tableView's margin settings
preservesSuperviewLayoutMargins = false
}
如果您希望在Github上进行检查,请参见this link。
有关移除的PR以及说明,可以在here中找到。