提问人:user3570727 提问时间:9/11/2014 最后编辑:Shobhakar Tiwariuser3570727 更新时间:4/30/2020 访问量:187485
iOS 8 UITableView 分隔符插图 0 不起作用
iOS 8 UITableView separator inset 0 not working
问:
我有一个应用程序,其中的分隔符插图设置为自定义值 - 右、左。这在 中完美工作,但是在我看到分隔符插图设置为右侧的默认值。即使在它设置为 的 xib 文件中,它仍然显示不正确。UITableView
0
0
iOS 7.x
iOS 8.0
15
0
如何删除分隔页边距?UITableViewCell
答:
精 氨 酸!!!在玩完之后,在你的子类中这样做:Cell
- (UIEdgeInsets)layoutMargins
{
return UIEdgeInsetsZero;
}
或为我设置修复它。cell.layoutMargins = UIEdgeInsetsZero;
评论
separatorInset
在 Swift 中,它稍微烦人一些,因为它是一个属性,所以你必须覆盖 getter 和 setter。layoutMargins
override var layoutMargins: UIEdgeInsets {
get { return UIEdgeInsetsZero }
set(newVal) {}
}
这将有效地使只读,这在我的情况下很好。layoutMargins
评论
我相信这与我在这里提出的问题相同: 删除 iOS 8 UITableView for XCode 6 iPhone 模拟器上的 SeparatorInset
在 iOS 8 中,继承自 的所有对象都有一个新属性。因此,在 iOS 7.x 中设置 的解决方案将无法删除您在 iOS 8 的 UITableView 上看到的空白。UIView
SeparatorInset
新属性称为“layoutMargins”。
@property(nonatomic) UIEdgeInsets layoutMargins
Description The default spacing to use when laying out content in the view.
Availability iOS (8.0 and later)
Declared In UIView.h
Reference UIView Class Reference
解决方案:-
-(void)tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath{
if ([tableView respondsToSelector:@selector(setSeparatorInset:)]) {
[tableView setSeparatorInset:UIEdgeInsetsZero];
}
if ([tableView respondsToSelector:@selector(setLayoutMargins:)]) {
[tableView setLayoutMargins:UIEdgeInsetsZero];
}
if ([cell respondsToSelector:@selector(setLayoutMargins:)]) {
[cell setLayoutMargins:UIEdgeInsetsZero];
}
}
如果在未检查是否存在的情况下进行设置,则应用程序将在 iOS 7.x 上崩溃。因此,最好的方法是先检查是否存在。cell.layoutMargins = UIEdgeInsetsZero;
layoutMargins
layoutMargins
setLayoutMargins:UIEdgeInsetsZero
评论
iOS 8.0 在单元格和表视图上引入了 layoutMargins 属性。
此属性在 iOS 7.0 上不可用,因此您需要确保在分配它之前进行检查!
简单的解决方法是按照@user3570727的建议对单元格进行子类化并覆盖布局边距属性。但是,您将失去任何系统行为,例如从安全区域继承边距,因此我不建议使用以下解决方案:
(目标C)
-(UIEdgeInsets)layoutMargins {
return UIEdgeInsetsZero // override any margins inc. safe area
}
(斯威夫特 4.2):
override var layoutMargins: UIEdgeInsets { get { return .zero } set { } }
如果您不想重写该属性,或者需要有条件地设置它,请继续阅读。
除了该属性之外,Apple 还向单元格添加了一个属性,该属性将阻止它继承“表视图”的边距设置。设置此属性后,允许单元格独立于表格视图配置自己的边距。将其视为覆盖。layoutMargins
此属性称为 ,如果将其设置为 ,则允许单元格的设置覆盖 TableView 上设置的任何内容。它既节省了时间(您不必修改表视图的设置),又更简洁。请参考迈克·阿卜杜拉(Mike Abdullah)的回答以获取详细说明。preservesSuperviewLayoutMargins
NO
layoutMargin
layoutMargin
注意:以下是单元格级边距设置的干净实现,如 Mike Abdullah 的回答中所表达的那样。设置单元格的 preservesSuperviewLayoutMargins=NO
将确保“表视图”不会覆盖单元格设置。如果您确实希望整个表格视图具有一致的边距,请相应地调整您的代码。
设置单元格边距:
-(void)tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath
{
// Remove seperator inset
if ([cell respondsToSelector:@selector(setSeparatorInset:)]) {
[cell setSeparatorInset:UIEdgeInsetsZero];
}
// 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:UIEdgeInsetsZero];
}
}
斯威夫特 4:
func tableView(_ tableView: UITableView, willDisplay cell: UITableViewCell, forRowAt indexPath: IndexPath) {
// Remove seperator inset
if cell.responds(to: #selector(setter: UITableViewCell.separatorInset)) {
cell.separatorInset = .zero
}
// Prevent the cell from inheriting the Table View's margin settings
if cell.responds(to: #selector(setter: UITableViewCell.preservesSuperviewLayoutMargins)) {
cell.preservesSuperviewLayoutMargins = false
}
// Explictly set your cell's layout margins
if cell.responds(to: #selector(setter: UITableViewCell.layoutMargins)) {
cell.layoutMargins = .zero
}
}
将单元格上的属性设置为 NO 应防止表视图覆盖单元格边距。在某些情况下,它似乎无法正常工作。preservesSuperviewLayoutMargins
如果全部失败,您可以暴力破解表视图边距:
-(void)viewDidLayoutSubviews
{
[super viewDidLayoutSubviews];
// Force your tableview margins (this may be a bad idea)
if ([self.tableView respondsToSelector:@selector(setSeparatorInset:)]) {
[self.tableView setSeparatorInset:UIEdgeInsetsZero];
}
if ([self.tableView respondsToSelector:@selector(setLayoutMargins:)]) {
[self.tableView setLayoutMargins:UIEdgeInsetsZero];
}
}
斯威夫特 4:
func viewDidLayoutSubviews() {
super.viewDidLayoutSubviews()
// Force your tableview margins (this may be a bad idea)
if tableView.responds(to: #selector(setter: UITableView.separatorInset)) {
tableView.separatorInset = .zero
}
if tableView.responds(to: #selector(setter: UITableView.layoutMargins)) {
tableView.layoutMargins = .zero
}
}
...你去吧!这应该适用于 iOS 7 和 8。
编辑:穆罕默德·萨利赫(Mohamed Saleh)引起了我的注意,iOS 9中可能发生了一些变化。如果要自定义插图或边距,则可能需要将“表格视图”设置为。您的里程可能会有所不同,这没有很好的记录。cellLayoutMarginsFollowReadableWidth
NO
此属性仅存在于 iOS 9 中,因此请务必在设置前进行检查。
if([myTableView respondsToSelector:@selector(setCellLayoutMarginsFollowReadableWidth:)])
{
myTableView.cellLayoutMarginsFollowReadableWidth = NO;
}
斯威夫特 4:
if myTableView.responds(to: #selector(setter: self.cellLayoutMarginsFollowReadableWidth)) {
myTableView.cellLayoutMarginsFollowReadableWidth = false
}
(iOS 8 UITableView 分隔符插图 0 中的以上代码不起作用)
编辑:这是一个纯粹的Interface Builder方法:
注意:iOS 11更改并简化了大部分此行为,更新即将推出...
评论
cell.preservesSuperviewLayoutMargins = NO
cell.preservesSuperviewLayoutMargins
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
至于 cdstamper 建议而不是表格视图,在单元格的 layoutSubview 方法中添加以下行对我有用。
- (void)layoutSubviews
{
[super layoutSubviews];
if ([self respondsToSelector:@selector(setSeparatorInset:)])
[self setSeparatorInset:UIEdgeInsetsZero];
if ([self respondsToSelector:@selector(setPreservesSuperviewLayoutMargins:)])
{
[self setPreservesSuperviewLayoutMargins:NO];;
}
if ([self respondsToSelector:@selector(setLayoutMargins:)])
{
[self setLayoutMargins:UIEdgeInsetsZero];
}
}
迅速:
override func viewDidLoad() {
super.viewDidLoad()
if self.tableView.respondsToSelector("setSeparatorInset:") {
self.tableView.separatorInset = UIEdgeInsetsZero
}
if self.tableView.respondsToSelector("setLayoutMargins:") {
self.tableView.layoutMargins = UIEdgeInsetsZero
}
self.tableView.layoutIfNeeded() // <--- this do the magic
}
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
...
if cell.respondsToSelector("setSeparatorInset:") {
cell.separatorInset = UIEdgeInsetsZero
}
if cell.respondsToSelector("setLayoutMargins:") {
cell.layoutMargins = UIEdgeInsetsZero
}
return cell
}
大多数答案都显示了在单元格和表格视图的各种方法(即 、 、 等)上设置的分隔符插图和布局边距,但我发现将它们放入效果很好。似乎是最干净的方式。viewDidLayoutSubviews
willDisplayCell
cellForRowAtIndexPath
// kill insets for iOS 8
if ([[UIDevice currentDevice].systemVersion floatValue] >= 8) {
cell.preservesSuperviewLayoutMargins = NO;
[cell setLayoutMargins:UIEdgeInsetsZero];
}
// iOS 7 and later
if ([cell respondsToSelector:@selector(setSeparatorInset:)])
[cell setSeparatorInset:UIEdgeInsetsZero];
使用以下代码片段避免IOS 8和7中UITableView不必要的填充问题。
-(void)tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath{
if ([tableView respondsToSelector:@selector(setSeparatorInset:)])
{
[tableView setSeparatorInset:UIEdgeInsetsZero];
}
if ([tableView respondsToSelector:@selector(setLayoutMargins:)])
{
[tableView setLayoutMargins:UIEdgeInsetsZero];
}
if ([cell respondsToSelector:@selector(setLayoutMargins:)])
{
[cell setLayoutMargins:UIEdgeInsetsZero];
}
}
这是在 Swift 中对我有用的代码:
override func viewDidLoad()
{
super.viewDidLoad()
...
if tableView.respondsToSelector("setSeparatorInset:") {
tableView.separatorInset = UIEdgeInsetsZero
}
}
func tableView(tableView: UITableView, willDisplayCell cell: UITableViewCell,forRowAtIndexPath indexPath: NSIndexPath)
{
if cell.respondsToSelector("setSeparatorInset:") {
cell.separatorInset.left = CGFloat(0.0)
}
if tableView.respondsToSelector("setLayoutMargins:") {
tableView.layoutMargins = UIEdgeInsetsZero
}
if cell.respondsToSelector("setLayoutMargins:") {
cell.layoutMargins.left = CGFloat(0.0)
}
}
这对我来说似乎是最干净的(目前),因为所有 cell/tableView 边缘/边距调整都是在方法中完成的,而不会将不必要的代码塞入 .tableView:willDisplayCell:forRowAtIndexPath:
tableView:cellForRowAtIndexPath:
顺便说一句,我只设置单元格的左分隔符Inset/layoutMargins,因为在这种情况下,我不想搞砸我在单元格中设置的约束。
代码更新到 Swift 2.2:
override func viewDidLoad() {
super.viewDidLoad()
if tableView.respondsToSelector(Selector("setSeparatorInset:")) {
tableView.separatorInset = UIEdgeInsetsZero
}
}
override func tableView(tableView: UITableView, willDisplayCell cell: UITableViewCell,forRowAtIndexPath indexPath: NSIndexPath) {
if cell.respondsToSelector(Selector("setSeparatorInset:")) {
cell.separatorInset.left = CGFloat(0.0)
}
if tableView.respondsToSelector(Selector("setLayoutMargins:")) {
tableView.layoutMargins = UIEdgeInsetsZero
}
if cell.respondsToSelector(Selector("setLayoutMargins:")) {
cell.layoutMargins.left = CGFloat(0.0)
}
}
评论
让我们花点时间了解这个问题,然后再盲目地冲进去尝试解决问题。
在调试器中快速浏览一下就会发现分隔线是 的子视图。似乎单元本身对这些线的布局负有相当大的责任。UITableViewCell
iOS 8 引入了布局边距的概念。默认情况下,视图的布局边距位于所有边,并且它们继承自祖先视图。8pt
据我们所知,在布置其分隔线时,选择尊重左侧布局边距,用它来约束左侧插图。UITableViewCell
综上所述,要实现所需的真正零点,我们需要:
- 将左侧布局边距设置为
0
- 停止任何继承的边距覆盖该边距
这样说来,这是一个非常简单的任务:
cell.layoutMargins = UIEdgeInsetsZero;
cell.preservesSuperviewLayoutMargins = NO;
注意事项:
- 此代码只需要在每个单元运行一次(毕竟您只是配置单元格的属性),并且当您选择执行它时并没有什么特别之处。做你觉得最干净的事情。
- 遗憾的是,这两个属性都无法在Interface Builder中配置,但如果需要,您可以指定用户定义的运行时属性。
preservesSuperviewLayoutMargins
- 显然,如果您的应用也面向早期的操作系统版本,则需要避免执行上述代码,直到在 iOS 8 及更高版本上运行。
- 您可以将祖先视图(例如表)配置为也具有左边距,而不是设置 ,但这本身似乎更容易出错,因为您无法控制整个层次结构。
preservesSuperviewLayoutMargins
0
- 只设置左边距并保留其他边距可能会稍微干净一些。
0
- 如果您想在纯样式表格底部绘制的“额外”分隔符上插入 0,我猜这也需要在表格级别指定相同的设置(没有尝试过这个!
UITableView
评论
[self.tableView setSeparatorInset:UIEdgeInsetsMake(0, 0, 0, 0)];
layoutMargins
preservesSuperviewLayoutMargins
separatorInset
UITableViewCell
UIEdgeInsets
UITableView
UITableViewCell
而不是更新和每次单元格滚动(使用 ),我建议在以下位置进行一次:preservesSuperviewLayoutMargins
layoutMargins
willDisplayCell
cellForRowAtIndexPath:
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell = super.tableView(tableView, cellForRowAtIndexPath: indexPath)
cell.preservesSuperviewLayoutMargins = false
cell.layoutMargins = UIEdgeInsetsZero
return cell
}
iOS 在单元格和表视图上引入了 layoutMargins 属性。
此属性在 iOS 7.0 中不可用,因此您需要确保在分配它之前进行检查!
但是,Apple 已将一个名为 preservesSuperviewLayoutMargins 的属性添加到单元格中,该属性将阻止它继承表视图的边距设置。这样,单元格就可以独立于表格视图配置自己的边距。将其视为覆盖。
此属性称为 preservesSuperviewLayoutMargins,将其设置为 NO 可以允许您使用自己的单元格的 layoutMargin 设置覆盖表视图的 layoutMargin 设置。它既节省了时间(您不必修改表视图的设置),又更简洁。请参考迈克·阿卜杜拉(Mike Abdullah)的回答以获取详细说明。
注意:这是适当的、不那么混乱的实现,正如迈克·阿卜杜拉的回答所表达的那样;设置单元格的 preservesSuperviewLayoutMargins=NO 将确保表视图不会覆盖单元格设置。
第一步 - 设置单元格边距:
/*
Tells the delegate that the table view is about to draw a cell for a particular row.
*/
override func tableView(tableView: UITableView, willDisplayCell cell: UITableViewCell,
forRowAtIndexPath indexPath: NSIndexPath)
{
// Remove separator inset
if cell.respondsToSelector("setSeparatorInset:") {
cell.separatorInset = UIEdgeInsetsZero
}
// Prevent the cell from inheriting the Table View's margin settings
if cell.respondsToSelector("setPreservesSuperviewLayoutMargins:") {
cell.preservesSuperviewLayoutMargins = false
}
// Explictly set your cell's layout margins
if cell.respondsToSelector("setLayoutMargins:") {
cell.layoutMargins = UIEdgeInsetsZero
}
}
将单元格的 preservesSuperviewLayoutMargins 属性设置为 NO 应防止表视图覆盖单元格边距。在某些情况下,它似乎无法正常运行。
第二步 - 只有当所有失败时,您都可以暴力破解表视图边距:
/*
Called to notify the view controller that its view has just laid out its subviews.
*/
override func viewDidLayoutSubviews() {
super.viewDidLayoutSubviews()
// Force your tableview margins (this may be a bad idea)
if self.tableView.respondsToSelector("setSeparatorInset:") {
self.tableView.separatorInset = UIEdgeInsetsZero
}
if self.tableView.respondsToSelector("setLayoutMargins:") {
self.tableView.layoutMargins = UIEdgeInsetsZero
}
}
...你去吧!这应该适用于 iOS 8 和 iOS 7。
注意:使用 iOS 8.1 和 7.1 进行测试,就我而言,我只需要使用本说明的第一步。
仅当呈现的单元格下方有未填充的单元格时,才需要执行第二步,即。如果表大于表模型中的行数。不执行第二步将导致不同的分隔符偏移。
评论
willDisplayCell
让我们按照我的代码做:
-(void)tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath{
if ([tableView respondsToSelector:@selector(setSeparatorInset:)]) {
[tableView setSeparatorInset:UIEdgeInsetsZero];
}
if ([tableView respondsToSelector:@selector(setLayoutMargins:)]) {
[tableView setLayoutMargins:UIEdgeInsetsZero];
}
if ([tableView respondsToSelector:@selector(setLayoutMargins:)]) {
cell.preservesSuperviewLayoutMargins = NO;
[cell setLayoutMargins:UIEdgeInsetsZero];
}
if ([cell respondsToSelector:@selector(setSeparatorInset:)]){
[cell setSeparatorInset:UIEdgeInsetsZero];
}
}
我通过这样做使它工作:
tableView.separatorInset = UIEdgeInsetsZero;
tableView.layoutMargins = UIEdgeInsetsZero;
cell.layoutMargins = UIEdgeInsetsZero;
可以在应用程序启动时(在加载 UI 之前)使用 UIAppearance 一次,将其设置为默认全局设置:
// iOS 7:
[[UITableView appearance] setSeparatorStyle:UITableViewCellSeparatorStyleSingleLine];
[[UITableView appearance] setSeparatorInset:UIEdgeInsetsZero];
[[UITableViewCell appearance] setSeparatorInset:UIEdgeInsetsZero];
// iOS 8:
if ([UITableView instancesRespondToSelector:@selector(setLayoutMargins:)]) {
[[UITableView appearance] setLayoutMargins:UIEdgeInsetsZero];
[[UITableViewCell appearance] setLayoutMargins:UIEdgeInsetsZero];
[[UITableViewCell appearance] setPreservesSuperviewLayoutMargins:NO];
}
这样,您可以保持 UIViewController 的代码干净,并且始终可以根据需要重写它。
我浏览了所有这些精彩的答案,并意识到它们中的大多数都不适用于iOS 8,或者确实有效,但是分隔符在动画过程中会改变大小,从而导致不必要的闪烁。这是我在创建窗口之前在我的应用程序委托中最终执行的操作:
[[UITableView appearance] setSeparatorInset:UIEdgeInsetsZero];
[[UITableViewCell appearance] setSeparatorInset:UIEdgeInsetsZero];
if ([UITableView instancesRespondToSelector:@selector(setLayoutMargins:)]) {
[[UITableView appearance] setLayoutMargins:UIEdgeInsetsZero];
[[UITableViewCell appearance] setLayoutMargins:UIEdgeInsetsZero];
[[UITableViewCell appearance] setPreservesSuperviewLayoutMargins:NO];
}
这是我添加到我的 UITableViewController 的内容:
-(void)viewDidLayoutSubviews
{
[super viewDidLayoutSubviews];
if ([self.tableView respondsToSelector:@selector(setSeparatorInset:)]) {
[self.tableView setSeparatorInset:UIEdgeInsetsZero];
}
if ([self.tableView respondsToSelector:@selector(setLayoutMargins:)]) {
[self.tableView setLayoutMargins:UIEdgeInsetsZero];
}
}
我不需要添加任何其他内容。感谢所有提供关键部分的人。
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
// ... Get the cell
cell.separatorInset = UIEdgeInsetsMake(0.f, 20.f, 0.f, [UIScreen mainScreen].bounds.size.width - 20);
// others
return cell;
}
对于要隐藏分隔符的任何特定单元格。
Lukasz 在 Swift 中的回答:
// iOS 7:
UITableView.appearance().separatorStyle = .SingleLine
UITableView.appearance().separatorInset = UIEdgeInsetsZero
UITableViewCell.appearance().separatorInset = UIEdgeInsetsZero
// iOS 8:
if UITableView.instancesRespondToSelector("setLayoutMargins:") {
UITableView.appearance().layoutMargins = UIEdgeInsetsZero
UITableViewCell.appearance().layoutMargins = UIEdgeInsetsZero
UITableViewCell.appearance().preservesSuperviewLayoutMargins = false
}
Swift for iOS 8 中的简单解决方案,带有自定义UITableViewCell
override func awakeFromNib() {
super.awakeFromNib()
self.layoutMargins = UIEdgeInsetsZero
self.separatorInset = UIEdgeInsetsZero
}
通过这种方式,您只设置一次,而不是像上面大多数答案所建议的那样对每次都进行设置。layoutMargin
separatorInset
willDisplayCell
如果您使用的是自定义,这是执行此操作的正确位置。
否则,您应该在 .UITableViewCell
tableView:cellForRowAtIndexPath
再提示一下:你不需要设置,因为默认值已经是!preservesSuperviewLayoutMargins = false
NO
以比得票最多的答案更紧凑的方式......
- (void)tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath {
if ([cell respondsToSelector:@selector(setSeparatorInset:)] && [cell respondsToSelector:@selector(setPreservesSuperviewLayoutMargins:)] && [cell respondsToSelector:@selector(setLayoutMargins:)]) {
[cell setSeparatorInset:UIEdgeInsetsZero];
[cell setPreservesSuperviewLayoutMargins:NO];
[cell setLayoutMargins:UIEdgeInsetsZero];
}
}
在 iOS8 中:
将其添加到我的 UITableViewCell 子类中:
- (UIEdgeInsets)layoutMargins {
return UIEdgeInsetsZero;
}
并将其转换为“tableView:cellForRowAtIndexPath”或“tableView:willDisplayCell”:
[editCell setSeparatorInset:UIEdgeInsetsZero];
为我工作。
我对上述任何解决方案都没有任何真正的运气。我正在将 NIB 文件用于我的表格单元格。我通过添加一个高度为 1 的标签来“修复”这个问题。我将标签的背景更改为黑色,将标签固定在笔尖的底部,然后将其余内容的底部固定到添加的标签上。现在我的细胞底部有一个黑色边框。
对我来说,这感觉更像是一种黑客攻击,但它确实有效。
我唯一的其他选择就是完全消除边界。我还在决定我是否要这样做。
iOS 8 及更高版本。Swift 2.0 及更高版本:
override func tableView(tableView: UITableView, willDisplayCell cell: UITableViewCell, forRowAtIndexPath indexPath: NSIndexPath) {
cell.separatorInset = UIEdgeInsetsZero
if #available(iOS 8.0, *) {
cell.layoutMargins = UIEdgeInsetsZero
} else {
// Fallback on earlier versions
}
}
在看到 3 楼的答案后,我试图弄清楚在 TableView 和 TableViewCell 之间设置分隔符的关系,并做了一些测试。以下是我的结论:
我们可以认为将单元格的分隔符设置为零必须分两步移动分隔符:第一步是将单元格的分隔符设置为零。第二步是将单元格的 marginlayout 设置为零。
设置 TableView 的 separatorinset 和 marginlayout 可能会影响 Cell 的 separatorinset。但是,从测试中,我发现 TableView 的分隔符似乎毫无用处,TableView 的 marginlayout 实际上会影响单元格的 marginlayout。
set Cell's PreservesSuperviewLayoutMargins = false,可以切断 TableView 对 Cells 的 marginlayout 影响。
解决方案之一:
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell { var cell = UITableViewCell() cell.preservesSuperviewLayoutMargins = false cell.separatorInset = UIEdgeInsetsZero cell.layoutMargins = UIEdgeInsetsZero return cell }
添加这个片段,在 Swift 中简单优雅,在 iOS8 中对我有用:)
// tableview single line
func tableView(tableView: UITableView, willDisplayCell cell: UITableViewCell, forRowAtIndexPath indexPath: NSIndexPath) {
cell.preservesSuperviewLayoutMargins = false
cell.layoutMargins = UIEdgeInsetsZero
}
这是我的解决方案。这适用于自定义单元格子类,只需将它们都添加到子类中即可。
- (UIEdgeInsets)layoutMargins { return UIEdgeInsetsMake(0, 10, 0, 10); }
2.
self.separatorInset = UIEdgeInsetsMake(0, 10, 0, 10);
而且很方便,您可以自定义分隔符的位置,而无需让您的设计师为您绘制一个..........
Swift 2.0 扩展
我只是想分享一个我所做的扩展,以从表视图单元格分隔符中删除边距。
extension UITableViewCell {
func removeMargins() {
if self.respondsToSelector("setSeparatorInset:") {
self.separatorInset = UIEdgeInsetsZero
}
if self.respondsToSelector("setPreservesSuperviewLayoutMargins:") {
self.preservesSuperviewLayoutMargins = false
}
if self.respondsToSelector("setLayoutMargins:") {
self.layoutMargins = UIEdgeInsetsZero
}
}
}
在上下文中使用:
let cell = tableView.dequeueReusableCellWithIdentifier("Cell", forIndexPath: indexPath) as! CustomCell
cell.removeMargins()
return cell
对于iOS 9,您需要添加:
if([myTableView respondsToSelector:@selector(setCellLayoutMarginsFollowReadableWidth:)])
{
myTableView.cellLayoutMarginsFollowReadableWidth = NO;
}
详情请参阅问题。
评论
这在 iOS 8 和 iOS 9 中对我来说非常有效。
对于OBJ-C
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
if ([tableView respondsToSelector:@selector(setSeparatorInset:)])
{
[tableView setSeparatorInset:UIEdgeInsetsZero];
}
if ([tableView respondsToSelector:@selector(setLayoutMargins:)])
{
[tableView setLayoutMargins:UIEdgeInsetsZero];
}
if ([cell respondsToSelector:@selector(setLayoutMargins:)])
{
[cell setLayoutMargins:UIEdgeInsetsZero];
}
return cell;
}
根据@cdstamper的回答,更好的地方是UITableViewCell的layoutSubviews,在你的单元格文件中(我设置了1%的间距,你可以设置为零),所以只需要在这里设置代码来处理所有情况(旋转和其他):
-(void)layoutSubviews
{
[super layoutSubviews];
if ([self respondsToSelector:@selector(setSeparatorInset:)]) {
[self setSeparatorInset:UIEdgeInsetsMake(0,self.bounds.size.width*0.01,0,self.bounds.size.width*0.01)];
}
if ([self respondsToSelector:@selector(setLayoutMargins:)]) {
[self setLayoutMargins:UIEdgeInsetsMake(0,self.bounds.size.width*0.01,0,self.bounds.size.width*0.01)];
}
}
这是全局删除插图的简单方法。
在:UITableViewCell+Extensions.swift
import UIKit
extension UITableViewCell {
override public var layoutMargins: UIEdgeInsets {
get { return UIEdgeInsetsZero }
set { }
}
}
在:AppDelegate
application:didFinishLaunchingWithOptions:
UITableViewCell.appearance().separatorInset = UIEdgeInsetsZero
您可能会想 a) 也只是在扩展中覆盖,或者 b) 将外观代理设置为 。两者都行不通。即使被指示为属性,尝试将其作为属性(或方法)重写也会生成编译器错误。为 ' 设置外观代理(或者,就此而言,也为 's 和 设置外观代理)不起作用。separatorInset
layoutMargins
separatorInset
UITableViewCell
layoutMargins
UITableView
layoutMargins
separatorInset
XCode 7.1 iOS 7、8、9:
只需将以下两行放在 TabelViewCell 中:
self.layoutMargins = UIEdgeInsetsZero;
self.preservesSuperviewLayoutMargins = false;
这对我有用
我的解决方案是将 UIView 添加为单元格子视图的容器。然后将此 UIView 约束(顶部、底部、尾随、前导)设置为 0 磅。所有不必要的质量都消失了。显示逻辑的图像
对我来说,简单的线条就完成了工作
cell.layoutMargins = UIEdgeInsetsZero
评论
使用情节提要更改分隔符插入自定义左 0 和右 0, 如果要将分隔符隐藏为“无” 见上图
使用 Swift 2.2
创建 UITableViewCell 扩展
import UIKit
extension UITableViewCell {
func removeMargins() {
if self.respondsToSelector(Selector("setSeparatorInset:")) {
self.separatorInset = UIEdgeInsetsZero
}
if self.respondsToSelector(Selector("setPreservesSuperviewLayoutMargins:")) {
self.preservesSuperviewLayoutMargins = false
}
if self.respondsToSelector(Selector("setLayoutMargins:")) {
self.layoutMargins = UIEdgeInsetsZero
}
}
}
现在,您可以在 cellForRowAtIndex
中使用
-(void)tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath
{
cell.removeMargins()//To remove seprator inset
}
在 Swift 中,你可以使用它
cell.selectionStyle = UITableViewCellSelectionStyle.None
cell.preservesSuperviewLayoutMargins = false
cell.separatorInset = UIEdgeInsetsZero
cell.layoutMargins = UIEdgeInsetsZero
经过大量调查...
这是完全控制这些东西的唯一方法(我能找到的)
完全控制每个单元格上的分隔符插图和布局边距。在 .willDisplayCell
UITableviewDelegate
func tableView(tableView: UITableView, willDisplayCell cell: UITableViewCell, forRowAtIndexPath indexPath: NSIndexPath) {
cell.layoutMargins = UIEdgeInsetsZero
cell.contentView.layoutMargins = UIEdgeInsetsMake(0, 10, 0, 10)
cell.separatorInset = UIEdgeInsetsMake(0, 0, 0, 0)
}
单元格对象控制分隔符,而其他所有内容则控制。如果您的分隔符插入空间以意外的颜色显示,这应该可以解决它:contentView
cell.backgroundColor = cell.contentView.backgroundColor
只需添加以下代码即可解决此程序。
祝你好运!
-(void)tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath {
if ([cell respondsToSelector:@selector(setSeparatorInset:)]) {
[cell setSeparatorInset:UIEdgeInsetsZero];
}
if ([cell respondsToSelector:@selector(setLayoutMargins:)]) {
[cell setLayoutMargins:UIEdgeInsetsZero];
}
}
Swift 3.0 示例:
func tableView(_ tableView: UITableView, willDisplay cell: UITableViewCell, forRowAt indexPath: IndexPath) {
// removing seperator inset
if cell.responds(to: #selector(setter: UITableViewCell.separatorInset)) {
cell.separatorInset = .zero
}
// prevent the cell from inheriting the tableView's margin settings
if cell.responds(to: #selector(setter: UIView.preservesSuperviewLayoutMargins)) {
cell.preservesSuperviewLayoutMargins = false
}
// explicitly setting cell's layout margins
if cell.responds(to: #selector(setter: UITableViewCell.layoutMargins)) {
cell.layoutMargins = .zero
}
}
只需将这两行放在 cellForRowAtIndexPath 方法中即可
- 如果要将所有分隔线都从零开始 [单元格集SeparatorInset:UIEdgeInsetsZero]; [单元格 setLayoutMargins:UIEdgeInsetsZero];
如果要 特定的分隔线从零开始,假设这里是最后一行从零开始
if (indexPath.row == array.count-1)
{
[cell setSeparatorInset:UIEdgeInsetsZero];
[cell setLayoutMargins:UIEdgeInsetsZero];
}
else
tblView.separatorInset=UIEdgeInsetsMake(0, 10, 0, 0);
对我来说,除了这个解决方法(Swift 3.0)之外,没有一个有效:
extension UIColor {
static func colorWith(hex:String, alpha: CGFloat) -> UIColor {
var cString = hex.trimmingCharacters(in: .whitespacesAndNewlines).uppercased()
if cString.hasPrefix("#") {
cString.remove(at: cString.startIndex)
}
if cString.characters.count != 6 {
return UIColor.gray
}
var rgbValue:UInt32 = 0
Scanner(string: cString).scanHexInt32(&rgbValue)
return UIColor(red: CGFloat((rgbValue & 0xFF0000) >> 16) / 255.0,
green: CGFloat((rgbValue & 0x00FF00) >> 8) / 255.0,
blue: CGFloat( rgbValue & 0x0000FF) / 255.0,
alpha: alpha)
}
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: cellReuseIdendifier, for: indexPath)
cell.backgroundColor = UIColor.colorWith(hex: "c8c7cc", alpha: 1) // same color of line separator
return cell
}
只需覆盖“cellForRowAtIndexPath”并设置“cell.preservesSuperviewLayoutMargins = false”和“cell.separatorInset = UIEdgeInsets.zero”和“cell.layoutMargins = UIEdgeInsets.zero”
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell: LayoutTableViewCell! = tableView.dequeueReusableCell(withIdentifier: "LayoutCell") as? LayoutTableViewCell
let currentLayout = OrderLayouts()[indexPath.row]
cell.NameLabel?.text = currentLayout.name
cell.DescrLabel?.text = currentLayout.descr
if(GlobalVariables.debug){
cell.DescrLabel?.text = "\(currentLayout.id) \n \(currentLayout.descr)"
}
cell.preservesSuperviewLayoutMargins = false
cell.separatorInset = UIEdgeInsets.zero
cell.layoutMargins = UIEdgeInsets.zero
return cell
}
评论
[UIColor clearColor]
UITableViewCellSeparatorStyle